Import Upstream version 3.4.0

This commit is contained in:
zhouganqing 2022-12-16 10:44:57 +08:00
commit abf2402fc1
191 changed files with 52729 additions and 0 deletions

View File

@ -0,0 +1,35 @@
name: GNU/Linux (X11) build
on:
push:
pull_request:
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: install dependencies
run: |
sudo apt-get update
sudo apt-get install libgl-dev libglu1-mesa-dev libx11-dev libxrandr-dev libxi-dev
- name: generate makefile
run: cmake -DCMAKE_BUILD_TYPE=Release .
- name: build freeglut
run: make
- name: stage install
run: DESTDIR=freeglut-instdir make install
- uses: actions/upload-artifact@v3
with:
name: freeglut-instdir
path: freeglut-instdir
# vi:ts=2 sts=2 sw=2 expandtab:

34
.github/workflows/build_macosx_x11.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: MacOS X (X11) build
on:
push:
pull_request:
workflow_dispatch:
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: install dependencies
run: |
brew install libx11 libxi libxrandr libxxf86vm pkg-config mesa
- name: generate makefile
run: cmake -DCMAKE_BUILD_TYPE=Release -DFREEGLUT_BUILD_DEMOS=OFF -DOPENGL_gl_LIBRARY=/usr/local/lib/libGL.dylib .
- name: build freeglut
run: make
- name: stage install
run: DESTDIR=freeglut-instdir make install
- uses: actions/upload-artifact@v3
with:
name: freeglut-instdir
path: freeglut-instdir
# vi:ts=2 sts=2 sw=2 expandtab:

35
.github/workflows/build_win_msvc.yml vendored Normal file
View File

@ -0,0 +1,35 @@
name: Windows MSVC build
on:
push:
pull_request:
workflow_dispatch:
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- name: prepare environment
uses: microsoft/setup-msbuild@v1.0.2
- name: generate project files
run: cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_GENERATOR="Visual Studio 17 2022" -DCMAKE_INSTALL_PREFIX=freeglut-instdir .
- name: build freeglut
run: cmake --build . --config Release
- name: stage install
run: cmake --install .
- uses: actions/upload-artifact@v3
with:
name: freeglut-instdir
path: |
freeglut-instdir
bin
# vi:ts=2 sts=2 sw=2 expandtab:

39
.gitignore vendored Normal file
View File

@ -0,0 +1,39 @@
Makefile.in
Makefile
INSTALL
.deps
aclocal.m4
autom4te.cache
compile
config.guess
config.sub
configure
configure.cache
config.log
config.status
config.h
depcomp
install-sh
ltmain.sh
missing
stamp-h1
*.tar
*.tar.gz
*.tar.bz2
*.zip
*.o
*.a
*~
*.swp
cross-android
cross-woe
native
*.exe
*.dll
*.a
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
freeglut.pc
freeglut.rc
FreeGLUT/

51
AUTHORS Normal file
View File

@ -0,0 +1,51 @@
Current maintainers: John F. Fay, Diederick C. Niehorster, John Tsiombikas
Pawel W. Olszta <olszta@sourceforge.net>
the person to be blamed for freeglut
Andreas Umbach <marvin@dataway.ch>
the first person to contribute to the freeglut project,
contributed the cube and sphere geometry code
Steve Baker <sjbaker1@airmail.net>
joystick code (from his great PLIB), numerous hints
tips on the freeglut usability
and for taking the project over when Pawel bowed out
Christopher John Purnell
Don Heyse
Dave McClurg
John F. Fay
Norman Vine
Daniel Wagner
Sven Panne <sven.panne@aedion.de>
contributing to the project, using the product, and generally keeping it going
Brian Paul
Eric Sandall
giving us the oomph! to make an official release
James 'J.C.' Jones
designing the new website
John Tsiombikas <nuclear@member.fsf.org>
mostly on the UNIX/X11 side of things.
Sylvain Beucler
support for Android, X11/EGL, OpenGL(ES) 2.x, misc fixes
Manuel Bachmann
support for Wayland
Diederick C. Niehorster
Chris Marshall
Clive McCarthy
Eero Pajarre
Florian Echtler
Matti Lehtonen
Vincent Simonetti
support for BlackBerry
...and all the opengl-gamedev-l people that made Pawel start this project :)

672
CMakeLists.txt Normal file
View File

@ -0,0 +1,672 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.0.0 FATAL_ERROR)
PROJECT(freeglut C)
# for multiarch LIBDIR support (requires cmake>=2.8.8)
INCLUDE(GNUInstallDirs)
# NOTE: On Windows and Cygwin, the dll's are placed in the
# CMAKE_RUNTIME_OUTPUT_DIRECTORY, while their corresponding import
# libraries end up in CMAKE_ARCHIVE_OUTPUT_DIRECTORY. On other
# platforms, such as Linux, the shared libraries are put in
# CMAKE_ARCHIVE_OUTPUT_DIRECTORY instead.
# Static libraries end up in CMAKE_ARCHIVE_OUTPUT_DIRECTORY on all
# platforms.
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
# setup version numbers
# XXX: Update these for each release!
set(VERSION_MAJOR 3)
set(VERSION_MINOR 4)
set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
# Update fg_version.h to match the versions number here in cmake
CONFIGURE_FILE(src/fg_version.h.in src/fg_version.h)
# shared lib version numbers (XXX: change before release)
set(SO_MAJOR 3) # increment on backwards incompatible API/ABI changes
set(SO_MINOR 12) # increment on backwards compatible API additions
set(SO_REV 0) # increment if only internal changes happened between releases
# FREEGLUT_BUILD_SHARED_LIBS is already a standard CMake variable, but we need to
# re-declare it here so it will show up in the GUI.
# by default, we want to build both
OPTION(FREEGLUT_BUILD_SHARED_LIBS "Build FreeGLUT shared library." ON)
OPTION(FREEGLUT_BUILD_STATIC_LIBS "Build FreeGLUT static library." ON)
# option for whether warnings and errors should be printed
OPTION(FREEGLUT_PRINT_ERRORS "Lib prints errors to stderr" ON)
#MARK_AS_ADVANCED(FREEGLUT_PRINT_ERRORS)
OPTION(FREEGLUT_PRINT_WARNINGS "Lib prints warnings to stderr" ON)
#MARK_AS_ADVANCED(FREEGLUT_PRINT_WARNINGS)
# option to also copy .pdb files to install directory when executing
# INSTALL target
IF(MSVC)
OPTION(INSTALL_PDB "Also install .pdb files" ON)
ELSE()
SET(INSTALL_PDB OFF)
ENDIF()
# OpenGL ES support
IF(ANDROID)
OPTION(FREEGLUT_GLES "Use OpenGL ES (requires EGL)" ON)
ELSE()
OPTION(FREEGLUT_GLES "Use OpenGL ES (requires EGL)" OFF)
ENDIF()
# option to build either as "glut" (ON) or "freeglut" (OFF)
IF(WIN32)
OPTION(FREEGLUT_REPLACE_GLUT "Be a replacement for GLUT" OFF)
ELSE()
OPTION(FREEGLUT_REPLACE_GLUT "Be a replacement for GLUT" ON)
ENDIF()
IF(NOT WIN32)
# Wayland support
OPTION(FREEGLUT_WAYLAND "Use Wayland (no X11)" OFF)
ENDIF()
SET(FREEGLUT_HEADERS
include/GL/freeglut.h
include/GL/freeglut_ucall.h
include/GL/freeglut_ext.h
include/GL/freeglut_std.h
)
IF(FREEGLUT_REPLACE_GLUT)
LIST(APPEND FREEGLUT_HEADERS
include/GL/glut.h
)
ENDIF()
SET(FREEGLUT_SRCS
${FREEGLUT_HEADERS}
src/fg_callbacks.c
src/fg_cursor.c
src/fg_display.c
src/fg_ext.c
src/fg_font_data.c
src/fg_gamemode.c
src/fg_geometry.c
src/fg_gl2.c
src/fg_gl2.h
src/fg_init.c
src/fg_init.h
src/fg_internal.h
src/fg_callback_macros.h
src/fg_input_devices.c
src/fg_joystick.c
src/fg_main.c
src/fg_misc.c
src/fg_overlay.c
src/fg_spaceball.c
src/fg_state.c
src/fg_stroke_mono_roman.c
src/fg_stroke_roman.c
src/fg_structure.c
src/fg_teapot.c
src/fg_teapot_data.h
src/fg_videoresize.c
src/fg_window.c
)
# TODO: OpenGL ES requires a compatible version of these files:
IF(NOT FREEGLUT_GLES)
LIST(APPEND FREEGLUT_SRCS
src/fg_font.c
src/fg_menu.c
)
ELSE()
LIST(APPEND FREEGLUT_SRCS
src/gles_stubs.c
)
ENDIF()
IF(WIN32)
LIST(APPEND FREEGLUT_SRCS
src/mswin/fg_cursor_mswin.c
src/mswin/fg_display_mswin.c
src/mswin/fg_ext_mswin.c
src/mswin/fg_gamemode_mswin.c
src/mswin/fg_init_mswin.c
src/mswin/fg_internal_mswin.h
src/mswin/fg_input_devices_mswin.c
src/mswin/fg_joystick_mswin.c
src/mswin/fg_main_mswin.c
src/mswin/fg_menu_mswin.c
src/mswin/fg_spaceball_mswin.c
src/mswin/fg_state_mswin.c
src/mswin/fg_structure_mswin.c
src/mswin/fg_window_mswin.c
src/mswin/fg_cmap_mswin.c
${CMAKE_BINARY_DIR}/freeglut.rc # generated below from freeglut.rc.in
)
IF (MSVC AND NOT CMAKE_CL_64)
# .def file only for 32bit Windows builds (TODO: MSVC only right
# now, needed for any other Windows platform?)
LIST(APPEND FREEGLUT_SRCS
${CMAKE_BINARY_DIR}/freeglutdll.def # generated below from src/freeglutdll.def.in
)
ENDIF()
ELSEIF(ANDROID OR BLACKBERRY)
# BlackBerry and Android share some similar design concepts and ideas, as with many mobile devices.
# As such, some classes can be shared between the two. XXX: Possibly rename shareable classes to
# a more generic name. *_stub? *_mobile?
LIST(APPEND FREEGLUT_SRCS
src/android/fg_cursor_android.c
src/android/fg_ext_android.c
src/android/fg_gamemode_android.c
src/android/fg_joystick_android.c
src/android/fg_spaceball_android.c
)
IF(ANDROID)
LIST(APPEND FREEGLUT_SRCS
src/android/native_app_glue/android_native_app_glue.c
src/android/native_app_glue/android_native_app_glue.h
src/android/fg_internal_android.h
src/android/fg_init_android.c
src/android/fg_input_devices_android.c
src/android/fg_main_android.c
src/android/fg_main_android.h
src/android/fg_runtime_android.c
src/android/fg_state_android.c
src/android/fg_structure_android.c
src/android/fg_window_android.c
)
ELSE()
LIST(APPEND FREEGLUT_SRCS
src/blackberry/fg_internal_blackberry.h
src/blackberry/fg_init_blackberry.c
src/x11/fg_input_devices_x11.c
src/blackberry/fg_main_blackberry.c
src/blackberry/fg_state_blackberry.c
src/blackberry/fg_structure_blackberry.c
src/blackberry/fg_window_blackberry.c
)
ENDIF()
ELSE()
# UNIX (Wayland)
IF(FREEGLUT_WAYLAND)
LIST(APPEND FREEGLUT_SRCS
src/wayland/fg_cursor_wl.c
src/wayland/fg_ext_wl.c
src/wayland/fg_gamemode_wl.c
src/wayland/fg_init_wl.c
src/wayland/fg_internal_wl.h
src/wayland/fg_input_devices_wl.c
src/wayland/fg_main_wl.c
src/wayland/fg_state_wl.c
src/wayland/fg_structure_wl.c
src/wayland/fg_window_wl.c
# font, serial port & joystick code are agnostic
src/x11/fg_glutfont_definitions_x11.c
src/x11/fg_input_devices_x11.c
src/x11/fg_joystick_x11.c
)
# UNIX (X11)
ELSE()
LIST(APPEND FREEGLUT_SRCS
src/x11/fg_cursor_x11.c
src/x11/fg_ext_x11.c
src/x11/fg_gamemode_x11.c
src/x11/fg_glutfont_definitions_x11.c
src/x11/fg_init_x11.c
src/x11/fg_internal_x11.h
src/x11/fg_input_devices_x11.c
src/x11/fg_joystick_x11.c
src/x11/fg_main_x11.c
src/x11/fg_menu_x11.c
src/x11/fg_spaceball_x11.c
src/x11/fg_state_x11.c
src/x11/fg_structure_x11.c
src/x11/fg_window_x11.c
src/x11/fg_xinput_x11.c
src/x11/fg_cmap_x11.c
)
IF(NOT(FREEGLUT_GLES))
LIST(APPEND FREEGLUT_SRCS
src/x11/fg_internal_x11_glx.h
src/x11/fg_display_x11_glx.c
src/x11/fg_state_x11_glx.c
src/x11/fg_state_x11_glx.h
src/x11/fg_window_x11_glx.c
src/x11/fg_window_x11_glx.h
)
ENDIF()
ENDIF()
ENDIF()
# OpenGL ES requires EGL, and so does Wayland
IF(FREEGLUT_GLES OR FREEGLUT_WAYLAND)
LIST(APPEND FREEGLUT_SRCS
src/egl/fg_internal_egl.h
src/egl/fg_display_egl.c
src/egl/fg_ext_egl.c
src/egl/fg_init_egl.c
src/egl/fg_init_egl.h
src/egl/fg_state_egl.c
src/egl/fg_state_egl.h
src/egl/fg_structure_egl.c
src/egl/fg_structure_egl.h
src/egl/fg_window_egl.c
src/egl/fg_window_egl.h
)
ENDIF()
INCLUDE(CheckIncludeFiles)
IF(UNIX AND NOT(ANDROID OR BLACKBERRY OR FREEGLUT_WAYLAND))
FIND_PACKAGE(X11 REQUIRED)
INCLUDE_DIRECTORIES(${X11_X11_INCLUDE_PATH})
LIST(APPEND LIBS ${X11_X11_LIB})
IF(X11_Xrandr_FOUND)
SET(HAVE_X11_EXTENSIONS_XRANDR_H TRUE)
LIST(APPEND LIBS ${X11_Xrandr_LIB})
ENDIF()
IF(X11_xf86vmode_FOUND)
SET(HAVE_X11_EXTENSIONS_XF86VMODE_H TRUE)
LIST(APPEND LIBS ${X11_Xxf86vm_LIB})
ENDIF()
IF(X11_Xinput_FOUND)
# Needed for multi-touch:
CHECK_INCLUDE_FILES("${X11_Xinput_INCLUDE_PATH}/X11/extensions/XInput2.h" HAVE_X11_EXTENSIONS_XINPUT2_H)
LIST(APPEND LIBS ${X11_Xinput_LIB})
ELSE()
MESSAGE(FATAL_ERROR "Missing X11's XInput2.h (X11/extensions/XInput2.h)")
ENDIF()
ENDIF()
# FreeBSD and NetBSD joystick code uses libusbhid
IF(CMAKE_SYSTEM_NAME STREQUAL FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL NetBSD)
IF(HAVE_USBHID_H)
LIST(APPEND LIBS "-lusbhid")
ENDIF()
ENDIF()
# For OpenGL ES (GLES): compile with -DFREEGLUT_GLES to cleanly
# bootstrap headers inclusion in freeglut_std.h; this constant also
# need to be defined in client applications (e.g. through pkg-config),
# but do use GLES constants directly for all other needs
# GLES1 and GLES2 libraries are compatible and can be co-linked.
IF(FREEGLUT_GLES)
LIST(APPEND PUBLIC_DEFINITIONS -DFREEGLUT_GLES)
LIST(APPEND LIBS GLESv2 GLESv1_CM EGL)
ELSE()
# On OS X, we need to link against the X11 OpenGL libraries, NOT the Cocoa OpenGL libraries.
# To do that, you need to manually find two of the libraries before calling FindOpenGL
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
# get path where X11 libs are
get_filename_component(X11_LIB_PATH ${X11_Xi_LIB} DIRECTORY)
find_library(OPENGL_gl_LIBRARY NAME GL HINTS ${X11_LIB_PATH})
find_library(OPENGL_glu_LIBRARY NAME GLU HINTS ${X11_LIB_PATH})
endif()
FIND_PACKAGE(OpenGL REQUIRED)
LIST(APPEND LIBS ${OPENGL_gl_LIBRARY})
INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})
ENDIF()
# For Wayland: compile with -DFREEGLUT_WAYLAND and pull EGL
IF(FREEGLUT_WAYLAND)
ADD_DEFINITIONS(-DFREEGLUT_WAYLAND)
LIST(APPEND LIBS wayland-client wayland-cursor wayland-egl EGL xkbcommon)
ENDIF()
# lib m for math, not needed on windows
IF (NOT WIN32)
# For compilation:
LIST(APPEND LIBS m)
# For CHECK_FUNCTION_EXISTS:
LIST(APPEND CMAKE_REQUIRED_LIBRARIES m)
ENDIF()
IF(WIN32)
# hide insecure CRT warnings, common practice
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
IF(MSVC)
SET( CMAKE_DEBUG_POSTFIX "d" )
ENDIF(MSVC)
IF(NOT(MSVC_VERSION LESS "1600"))
# minimum requirement for WM_TOUCH device
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0601)
ADD_DEFINITIONS(-DWINVER=0x0601)
ELSEIF(NOT(MSVC_VERSION LESS "1300"))
# minimum requirement for spaceball device
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501)
ADD_DEFINITIONS(-DWINVER=0x0501)
ELSE()
# enable the use of Win2000 APIs (needed for really old compilers like MSVC6)
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0500)
ADD_DEFINITIONS(-DWINVER=0x0500)
ENDIF()
ENDIF()
IF(CMAKE_COMPILER_IS_GNUCC)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
IF(NOT(ANDROID OR BLACKBERRY OR FREEGLUT_WAYLAND))
# not setting -ansi as EGL/KHR headers doesn't support it
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic")
ENDIF()
ENDIF(CMAKE_COMPILER_IS_GNUCC)
IF(ANDROID)
# -landroid for ANativeWindow
# -llog for native Android logging
LIST(APPEND LIBS android log)
ELSEIF(BLACKBERRY)
# -lbps for event loop
# -screen for native screen
LIST(APPEND LIBS bps screen)
if(NOT PLAYBOOK)
# -lslog2 for logging
# -pps for low-level screen manipulation
LIST(APPEND LIBS slog2 pps)
ENDIF()
ENDIF()
INCLUDE(CheckFunctionExists)
INCLUDE(CheckTypeSize)
INCLUDE(CheckCCompilerFlag)
CHECK_INCLUDE_FILES(sys/types.h HAVE_SYS_TYPES_H)
CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H)
CHECK_INCLUDE_FILES(sys/time.h HAVE_SYS_TIME_H)
CHECK_INCLUDE_FILES(stdbool.h HAVE_STDBOOL_H)
CHECK_INCLUDE_FILES(sys/param.h HAVE_SYS_PARAM_H)
CHECK_INCLUDE_FILES(sys/ioctl.h HAVE_SYS_IOCTL_H)
CHECK_INCLUDE_FILES(fcntl.h HAVE_FCNTL_H)
CHECK_INCLUDE_FILES(usbhid.h HAVE_USBHID_H)
CHECK_FUNCTION_EXISTS(gettimeofday HAVE_GETTIMEOFDAY)
CHECK_FUNCTION_EXISTS(XParseGeometry HAVE_XPARSEGEOMETRY)
IF (NOT HAVE_XPARSEGEOMETRY)
LIST(APPEND FREEGLUT_SRCS
src/util/xparsegeometry_repl.c
src/util/xparsegeometry_repl.h)
SET(NEED_XPARSEGEOMETRY_IMPL TRUE)
ENDIF()
# decide on suitable type for internal time keeping, 64-bit if possible
CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H)
CHECK_INCLUDE_FILES(inttypes.h HAVE_INTTYPES_H)
IF (NOT (HAVE_STDINT_H OR HAVE_INTTYPES_H))
IF (MSVC)
# Some old Microsoft VC releases don't support unsigned long
# long, but all we care about is support for unsigned __int64 on
# MSVC, so test for presence of that type
CHECK_TYPE_SIZE("unsigned __int64" U__INT64 BUILTIN_TYPES_ONLY)
ELSEIF()
CHECK_TYPE_SIZE("unsigned long long" ULONG_LONG BUILTIN_TYPES_ONLY)
ENDIF()
ENDIF()
# The generated config.h is placed in the project's build directory, just to
# ensure that all CMake-generated files are kept away from the main source tree.
# As a result, the build directory must to be added to the include path list.
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_BINARY_DIR}/config.h)
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/src)
ADD_DEFINITIONS(-DHAVE_CONFIG_H)
IF(WIN32)
# we also have to generate freeglut.rc, which contains the version
# number
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/freeglut.rc.in ${CMAKE_BINARY_DIR}/freeglut.rc)
IF (MSVC AND NOT CMAKE_CL_64)
# .def file only for 32bit Windows builds with Visual Studio
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/src/freeglutdll.def.in ${CMAKE_BINARY_DIR}/freeglutdll.def)
ENDIF()
ENDIF()
IF(FREEGLUT_BUILD_SHARED_LIBS)
ADD_LIBRARY(freeglut SHARED ${FREEGLUT_SRCS})
ENDIF()
IF(FREEGLUT_BUILD_STATIC_LIBS)
ADD_LIBRARY(freeglut_static STATIC ${FREEGLUT_SRCS})
ENDIF()
SET(LIBNAME freeglut)
IF(WIN32)
IF(FREEGLUT_REPLACE_GLUT)
SET(LIBNAME glut)
ENDIF()
LIST(APPEND LIBS winmm gdi32)
IF(FREEGLUT_BUILD_SHARED_LIBS)
TARGET_COMPILE_DEFINITIONS(freeglut PRIVATE FREEGLUT_EXPORTS)
SET_TARGET_PROPERTIES(freeglut PROPERTIES OUTPUT_NAME ${LIBNAME})
ENDIF()
IF(FREEGLUT_BUILD_STATIC_LIBS)
TARGET_COMPILE_DEFINITIONS(freeglut_static PUBLIC FREEGLUT_STATIC)
IF(FREEGLUT_REPLACE_GLUT)
SET_TARGET_PROPERTIES(freeglut_static PROPERTIES OUTPUT_NAME ${LIBNAME})
ENDIF()
# need to set machine:x64 for linker, at least for VC10, and
# doesn't hurt for older compilers:
# http://public.kitware.com/Bug/view.php?id=11240#c22768
IF (CMAKE_CL_64)
SET_TARGET_PROPERTIES(freeglut_static PROPERTIES STATIC_LIBRARY_FLAGS "/machine:x64")
ENDIF()
ENDIF()
ELSE()
# on UNIX we need to make sure:
# - all shared libraries must have a soname/version, see :
# http://sourceware.org/autobook/autobook/autobook_91.html#SEC91
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
# Current: -version-info 12:0:9 -> 3.9.0
# Note: most platforms now prefer the latter major.minor.revision form
# (e.g. FreeBSD, cf. http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8765),
# or special-cased FreeGLUT long ago (e.g. .so.4 on OpenBSD), so
# the lack of support for current:revision:age in CMake should
# not be a problem.
# - the output library should be named glut so it'll be linkable with -lglut
# (unless FREEGLUT_REPLACE_GLUT is false).
# - the shared library should link to the dependency libraries so that the user
# won't have to link them explicitly (they shouldn't have to know that we depend
# on Xrandr or Xxf86vm)
IF(FREEGLUT_GLES)
SET(LIBNAME freeglut-gles)
ELSE()
IF(FREEGLUT_REPLACE_GLUT)
SET(LIBNAME glut)
ENDIF()
ENDIF()
IF(FREEGLUT_BUILD_SHARED_LIBS)
SET_TARGET_PROPERTIES(freeglut PROPERTIES VERSION ${SO_MAJOR}.${SO_MINOR}.${SO_REV} SOVERSION ${SO_MAJOR} OUTPUT_NAME ${LIBNAME})
ENDIF()
IF(FREEGLUT_BUILD_STATIC_LIBS)
SET_TARGET_PROPERTIES(freeglut_static PROPERTIES OUTPUT_NAME ${LIBNAME})
ENDIF()
IF(ANDROID)
# Not in CMake toolchain file, because the toolchain
# file is called several times and generally doesn't
# seem to be meant for modifying CFLAGS:
# '-mandroid' is not mandatory but doesn't hurt
# '-O0 -gstabs+' helps the currently buggy GDB port
# Too late to manipulate ENV: SET(ENV{CFLAGS} "$ENV{CFLAGS} -mandroid")
# Not using _INIT variables, they seem to be used internally only
IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mandroid")
ENDIF()
CHECK_C_COMPILER_FLAG(-O0 HAVE_O0_FLAG)
IF(HAVE_O0_FLAG)
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
ENDIF()
CHECK_C_COMPILER_FLAG(-gstabs+ HAVE_GSTABSP_FLAG)
IF(HAVE_gstabsp_FLAG)
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -gstabs+")
ENDIF()
ENDIF()
ENDIF()
IF(FREEGLUT_BUILD_SHARED_LIBS)
TARGET_LINK_LIBRARIES(freeglut ${LIBS})
TARGET_COMPILE_DEFINITIONS(freeglut PUBLIC ${PUBLIC_DEFINITIONS})
ENDIF()
IF(FREEGLUT_BUILD_STATIC_LIBS)
TARGET_LINK_LIBRARIES(freeglut_static ${LIBS})
TARGET_COMPILE_DEFINITIONS(freeglut_static PUBLIC ${PUBLIC_DEFINITIONS})
ENDIF()
IF(FREEGLUT_BUILD_SHARED_LIBS)
INSTALL(TARGETS freeglut EXPORT FreeGLUTTargets
RUNTIME DESTINATION bin
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION include
)
IF(INSTALL_PDB)
IF(CMAKE_GENERATOR MATCHES "^Visual Studio" OR
CMAKE_GENERATOR MATCHES "Ninja Multi-Config")
INSTALL(FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug/freeglut${CMAKE_DEBUG_POSTFIX}.pdb
DESTINATION bin
CONFIGURATIONS Debug
COMPONENT Devel)
ELSE()
INSTALL(FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/freeglut${CMAKE_DEBUG_POSTFIX}.pdb
DESTINATION bin
CONFIGURATIONS Debug
COMPONENT Devel)
ENDIF()
ENDIF()
ENDIF()
IF(FREEGLUT_BUILD_STATIC_LIBS)
INSTALL(TARGETS freeglut_static EXPORT FreeGLUTTargets
RUNTIME DESTINATION bin
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION include
)
ENDIF()
INSTALL(FILES ${FREEGLUT_HEADERS} DESTINATION include/GL COMPONENT Devel)
# Optionally build demos, on by default.
option( FREEGLUT_BUILD_DEMOS "Build FreeGLUT demos." ON )
SET(DEMO_LIBS ${OPENGL_glu_LIBRARY} ${LIBS})
# lib m for math, not needed on windows
IF (NOT WIN32)
LIST(APPEND DEMO_LIBS m)
ENDIF()
MACRO(ADD_DEMO name)
IF( FREEGLUT_BUILD_DEMOS )
IF(FREEGLUT_BUILD_SHARED_LIBS)
ADD_EXECUTABLE(${name} ${ARGN})
TARGET_LINK_LIBRARIES(${name} ${DEMO_LIBS} freeglut)
IF(WIN32 AND MSVC)
SET_TARGET_PROPERTIES(${name} PROPERTIES DEBUG_POSTFIX d)
ENDIF()
ENDIF()
IF(FREEGLUT_BUILD_STATIC_LIBS)
ADD_EXECUTABLE(${name}_static ${ARGN})
TARGET_LINK_LIBRARIES(${name}_static ${DEMO_LIBS} freeglut_static)
IF(WIN32 AND MSVC)
SET_TARGET_PROPERTIES(${name}_static PROPERTIES DEBUG_POSTFIX d)
ENDIF()
ENDIF()
ENDIF()
ENDMACRO()
ADD_DEMO(CallbackMaker progs/demos/CallbackMaker/CallbackMaker.c)
ADD_DEMO(Fractals progs/demos/Fractals/fractals.c)
ADD_DEMO(Fractals_random progs/demos/Fractals_random/fractals_random.c)
ADD_DEMO(Lorenz progs/demos/Lorenz/lorenz.c)
IF (NOT WIN32)
ADD_DEMO(One progs/demos/One/one.c)
ELSE()
ADD_DEMO(One progs/demos/One/one.c
progs/demos/One/one.rc)
ENDIF()
ADD_DEMO(resizer progs/demos/resizer/resizer.c)
ADD_DEMO(multi-touch progs/demos/multi-touch/multi-touch.c)
ADD_DEMO(shapes progs/demos/shapes/shapes.c
progs/demos/shapes/glmatrix.h
progs/demos/shapes/glmatrix.c)
ADD_DEMO(smooth_opengl3 progs/demos/smooth_opengl3/smooth_opengl3.c)
ADD_DEMO(spaceball progs/demos/spaceball/spaceball.c
progs/demos/spaceball/vmath.c
progs/demos/spaceball/vmath.h)
ADD_DEMO(joystick progs/demos/joystick/joystick.c)
ADD_DEMO(subwin progs/demos/subwin/subwin.c)
ADD_DEMO(timer progs/demos/timer/timer.c)
ADD_DEMO(timer_callback progs/demos/timer_callback/timer.c)
ADD_DEMO(keyboard progs/demos/keyboard/keyboard.c)
ADD_DEMO(indexed_color progs/demos/indexed_color/idxcol.c)
ADD_DEMO(3dview progs/demos/3dview/3dview.c)
# pkg-config support, to install at $(libdir)/pkgconfig
# Define static build dependencies
IF(WIN32)
SET(PC_LIBS_PRIVATE "-lopengl32 -lwinmm -lgdi32")
ELSEIF(FREEGLUT_GLES)
IF(ANDROID)
SET(PC_LIBS_PRIVATE "-llog -landroid -lGLESv2 -lGLESv1_CM -lEGL -lm")
ELSEIF(BLACKBERRY)
IF(PLAYBOOK)
SET(PC_LIBS_PRIVATE "-lbps -lscreen -lGLESv2 -lGLESv1_CM -lEGL -lm")
ELSE()
SET(PC_LIBS_PRIVATE "-lbps -lslog2 -lscreen -lGLESv2 -lGLESv1_CM -lEGL -lm")
ENDIF()
ELSEIF(FREEGLUT_WAYLAND)
SET(PC_LIBS_PRIVATE "-lwayland-client -lwayland-cursor -lwayland-egl -lGLESv2 -lGLESv1_CM -lEGL -lxkbcommon -lm")
ELSE()
SET(PC_LIBS_PRIVATE "-lX11 -lXxf86vm -lXrandr -lGLESv2 -lGLESv1_CM -lEGL -lm")
ENDIF()
ELSE()
IF(FREEGLUT_WAYLAND)
SET(PC_LIBS_PRIVATE "-lwayland-client -lwayland-cursor -lwayland-egl -lGL -lxkbcommon -lm")
ELSE()
SET(PC_LIBS_PRIVATE "-lX11 -lXxf86vm -lXrandr -lGL -lm")
ENDIF()
ENDIF()
# Client applications need to define FreeGLUT GLES version to
# bootstrap headers inclusion in freeglut_std.h:
SET(PC_LIBNAME ${LIBNAME})
SET(PC_FILENAME "${LIBNAME}.pc")
IF(FREEGLUT_GLES)
SET(PC_CFLAGS "-DFREEGLUT_GLES")
ENDIF()
IF(FREEGLUT_BUILD_STATIC_LIBS)
LIST(APPEND PC_CFLAGS -DFREEGLUT_STATIC)
ENDIF()
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/freeglut.pc.in ${CMAKE_BINARY_DIR}/freeglut.pc @ONLY)
INSTALL(FILES ${CMAKE_BINARY_DIR}/freeglut.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig/ RENAME ${PC_FILENAME} COMPONENT Devel)
# TODO: change the library and .pc name when building for GLES,
# e.g. -lglut-GLES
INCLUDE(CMakePackageConfigHelpers)
WRITE_BASIC_PACKAGE_VERSION_FILE(
"${CMAKE_CURRENT_BINARY_DIR}/FreeGLUT/FreeGLUTConfigVersion.cmake"
VERSION ${VERSION}
COMPATIBILITY AnyNewerVersion
)
# needs cmake 3.0 (as does the "INCLUDES DIRECTORY" argument to install(TARGETS)):
EXPORT(EXPORT FreeGLUTTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/FreeGLUT/FreeGLUTTargets.cmake"
NAMESPACE FreeGLUT::
)
CONFIGURE_FILE(FreeGLUTConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/FreeGLUT/FreeGLUTConfig.cmake"
@ONLY
)
SET(ConfigPackageLocation ${CMAKE_INSTALL_LIBDIR}/cmake/FreeGLUT)
INSTALL(EXPORT FreeGLUTTargets
FILE FreeGLUTTargets.cmake
NAMESPACE FreeGLUT::
DESTINATION ${ConfigPackageLocation}
)
INSTALL(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/FreeGLUT/FreeGLUTConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/FreeGLUT/FreeGLUTConfigVersion.cmake"
DESTINATION ${ConfigPackageLocation}
COMPONENT Devel
)

27
COPYING Normal file
View File

@ -0,0 +1,27 @@
Freeglut Copyright
------------------
Freeglut code without an explicit copyright is covered by the following
copyright:
Copyright (c) 1999-2000 Pawel W. Olszta. 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 or substantial portions of the Software.
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
PAWEL W. OLSZTA 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.
Except as contained in this notice, the name of Pawel W. Olszta shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Pawel W. Olszta.

3888
ChangeLog Normal file

File diff suppressed because it is too large Load Diff

1
FreeGLUTConfig.cmake.in Normal file
View File

@ -0,0 +1 @@
include("${CMAKE_CURRENT_LIST_DIR}/FreeGLUTTargets.cmake")

3
README.android Normal file
View File

@ -0,0 +1,3 @@
See http://freeglut.sourceforge.net/docs/android.php

23
README.blackberry Normal file
View File

@ -0,0 +1,23 @@
# ------------------------------------------------------------------------------
# BlackBerry CMake toolchain file, for use with the BlackBerry 10 NDK
# Requires cmake 2.6.3 or newer (2.8.3 or newer is recommended).
#
# Usage Linux:
# $ source /absolute/path/to/the/bbndk/bbndk-env.sh
# $ mkdir build
# $ cd build
# $ cmake .. -DCMAKE_TOOLCHAIN_FILE="../blackberry.toolchain.cmake" -DBLACKBERRY_ARCHITECTURE=arm -DFREEGLUT_GLES=ON -DFREEGLUT_BUILD_DEMOS=NO -DCMAKE_VERBOSE_MAKEFILE=TRUE -G "Eclipse CDT4 - Unix Makefiles"
# $ make -j8
#
# Usage Mac:
# Same as the steps on Linux
#
# Usage Windows:
# > /absolute/path/to/the/bbndk/bbndk-env.bat
# > mkdir build
# > cd build
# > cmake .. -DCMAKE_TOOLCHAIN_FILE="../blackberry.toolchain.cmake" -DBLACKBERRY_ARCHITECTURE=arm -DFREEGLUT_GLES=ON -DFREEGLUT_BUILD_DEMOS=NO -DCMAKE_VERBOSE_MAKEFILE=TRUE -G "Eclipse CDT4 - Unix Makefiles"
# > make -j8
#
To change which version of OpenGL to use, call glutInitContextVersion(1, 0) for OpenGL ES 1.x, glutInitContextVersion(2, 0) for OpenGL ES 2.0, or glutInitContextVersion(3, 0) for OpenGL ES 3.0.

80
README.cmake Normal file
View File

@ -0,0 +1,80 @@
How to build freeglut with CMake on Windows (MS Visual Studio)
--------------------------------------------------------------
1. Download CMake (http://www.cmake.org/cmake/resources/software.html).
Get one of the releases from the binary distribution section.
2. Run the CMake installer, install wherever you like.
3. Launch CMake via Start > Program Files > CMake 2.8 > CMake (GUI)
(note that the shortcut put by the installer on your desktop does NOT
point to the CMake GUI program!)
4. In the "Where is the source code" box, type or browse to the root
directory of your freeglut source (so that's /freeglut, not
/freeglut/src).
5. In the "Where to build the binaries" box, type or browse to any
folder you like - this will be where the Visual Studio solution will be
generated. This folder does not have to exist yet.
6. Hit the Configure button near the bottom of the window.
7. Pick your target compiler, make sure that its installed on your
system of course!
8. Answer Ok when asked if you want to create the build directory.
9. Wait for the configure process to finish.
10. The screen will now have some configuration options on it, for
instance specifying whether you want to build static and/or shared
libraries (see below for a complete list). When you've selected your
options, click the Configure button again.
11. The Generate button at the bottom will now be enabled. Click Generate.
12. The build files will now be generated in the location you picked.
You can now navigate to the build directory you specified in step 5.
Open the freeglut.sln file that was generated in your build directory,
and compile as usual
How to build freeglut on UNIX
-----------------------------
- Make sure you have cmake installed. Examples:
- Debian/Ubuntu: apt-get install cmake
- Fedora: yum install cmake
- FreeBSD: cd /usr/ports/devel/cmake && make install
Or directly from their website:
http://www.cmake.org/cmake/resources/software.html
- Make sure you have the basics for compiling code, such as C compiler
(e.g., GCC) and the make package.
- Also make sure you have packages installed that provide the relevant
header files for opengl (e.g., libgl1-mesa-dev on Debian/Ubuntu) and
the chosen backend :
- X11: x11 (e.g., libx11-dev, libxrandr-devel on Debian/Ubuntu) and
XInput (libxi-dev / libXi-devel)
- Wayland: wayland (e.g., libwayland-dev and libegl1-mesa-dev on
Debian/Ubuntu) and xkbcommon (libxkbcommon-dev /libxkbcommon-devel)
- Run 'cmake .' (or 'cmake . -DFREEGLUT_WAYLAND=ON' for Wayland) in the
freeglut directory to generate the makefile.
- Run 'make' to build, and 'make install' to install freeglut.
- If you wish to change any build options run 'ccmake .'
Breakdown of CMake configuration options
----------------------------------------
CMAKE_BUILD_TYPE [Empty, Debug, Release] Can be overriden by
passing it as a make variable during build.
CMAKE_INSTALL_PREFIX Installation prefix (e.g. /usr/local on UNIX)
FREEGLUT_BUILD_DEMOS [ON, OFF] Controls whether the demos are
built or not.
FREEGLUT_BUILD_SHARED_LIBS [ON, OFF] Build freeglut as a shared library
FREEGLUT_BUILD_STATIC_LIBS [ON, OFF] Build freeglut as a static library
FREEGLUT_GLES [ON, OFF] Link with GLEs libraries instead
of OpenGL
FREEGLUT_WAYLAND [ON, OFF] Link with Wayland libraries instead
of X11
FREEGLUT_PRINT_ERRORS [ON, OFF] Controls whether errors are
default handled or not when user does not
provide an error callback
FREEGLUT_PRINT_WARNINGS [ON, OFF] Controls whether warnings are
default handled or not when user does not
provide an warning callback
FREEGLUT_REPLACE_GLUT [ON, OFF] For non-Windows platforms,
freeglut is by default built as -lglut. if
off, built as -lfreeglut. On Windows,
libraries are always built as freeglut.
INSTALL_PDB [ON, OFF] MSVC only: controls whether debug
information files are included with the
install or not

209
README.cygwin_mingw Normal file
View File

@ -0,0 +1,209 @@
Glut then!
By Jean-Seb on Friday July 10, 2009, 00:18
Translated by Babelfish with a scrub from John F. Fay. For points of confusion
please refer to the original French version.
Freeglut is an open-source evolution of GLUT.
Under Windows, one can use it with Cygwin.
Easy? Yes, if one agrees to distribute "cygwin1.dll".
Let us help freeglut gain its independence !
Update 10/7/2009: generation of a library for linking without the DLL.
Grabbing the sources
* Download the sources for version 2.6.0 which integrates recent changes.
* Using version 2.6 is better than the 2.4-stable branch because many
bugs have been corrected.
* You will find the sources on the site of Freeglut:
o http://freeglut.sourceforge.net/
Goals
* We will create a DLL for Cygwin, and an independent static library
* We will also create a dynamic library, allowing linking with the DLL.
List of generated files
* freeglut.dll: a traditional DLL for the dynamic linkage.
* libfreeglut.a: the static library. The final program is autonomous (at
least for OpenGL).
* libfreeglutdll.a: the dynamic library. The final program needs
freeglut.dll.
Preparation
* Extract the files from the freeglut archive.
* Go in the directory src (located at the root of the Freeglut directory),
and create a "Gl" sub-directory
o In this sub-directory, copy the files of the directory "include/Gl"
* Why is it necessary to create a "Gl" directory for compilation?
o I needed it to simplify things during my tests.
o If not you can create the repertories directly, and copy the files
as indicated in the point installation (see below).
* Do a little housekeeping in /lib:
o Erase all the references to the glut, so as not to conflict with the
linking.
o This stage is optional, you can also choose to do the housekeeping
only after a successful compilation of Freeglut.
o In your enthusiasm to clean things up, be careful not to erase the
library glu32.lib (not to be confused with glut32.lib).
Compilation
* Forget the "./configure, make, make install" triptych.
o It does not go at all with Cygwin.
* Here Makefile which will make the deal:
#Makefile for Freeglut 2.6.0-rc and Cygwin
#To place in the directory 'src/Common'
sources=$ (wildcard *.c)
objs=$ (sources: .c=.o)
libname=freeglut
CFLAGS=-O2 - DTARGET_HOST_MS_WINDOWS - DX_DISPLAY_MISSING - DFREEGLUT_STATIC - I./
LDFLAGS=-lopengl32 - lgdi32 - lwinmm
nocyg=-mno-cygwin - mwindows
all: $ (objs)
#construction DLL related to cygwin1.dll
gcc $(nocyg) $(objs) -shared $(LDFLAGS) -o $(libname).dll
nm $(libname).dll | awk 'BEGIN { print "EXPORTS" } /T _glut/ {sub( /^.*T _/, "\t"); print}' > $(libname).def
dlltool --dllname $(libname).dll --input-def $(libname).def --output-lib lib$(libname)dll.a
#construction static library independent of cygwin
ar cr lib$(libname).a $(objs)
#pas inevitably obligatory (creation of an index to accelerate the accesses)
ranlib lib$(libname).a
%.o: %.c
gcc $(nocyg) -c $(CFLAGS) $<
clean:
rm -f *.o $(libname).dll $(libname).def lib$(libname)dll.a lib$(libname).a
Some remarks on the Makefile
* This makefile creates a DLL, a static library (a file, in other words) and
the dynamic library which will allow the use of the DLL.
* Do not try to strip the static library! You may not be able to compile
applications with static library any more.
o On the other hand, you can strip the final executable obtained after
compiling your application.
* I chose to call the DLL and the libraries by their "true names":
freeglut.dll libfreeglutdll.a and libfreeglut.a.
o Script configures recreated (for reasons of compatibility with the
old GLUT library) glut.dll and libglut.a.
o During the my tests, I had conflicts with an authentic "glut" which
trailed in my "/lib". I decided to call the things by their name, in
order to avoid confusions.
o Nothing prevents you from renaming the DLL, if you need to use GLUT
programs which you cannot recompile.
* The dynamic library is generated starting from the DLL.
o For reasons of brevity, I used awk. It generates the export file
used by dlltool.
o The only notable thing is the selection of the functions whose name
starts with _glut, in order to avoid including in the dynamic
library the functions that are not related to freeglut.
o then, one uses dlltool in a very traditional way.
nm $(libname).dll | awk 'BEGIN { print "EXPORTS" } /T _glut/ {sub( /^.*T _/, "\t"); print}' > $(libname).def
dlltool --dllname $(libname).dll --input-def $(libname).def --output-lib lib$(libname)dll.a
Installation
* Copy libfreeglut.a, libfreeglutdll.a into the Cygwin directory /lib.
* Copy freglut.dll in the system32 of Windows (this is practical, but not
clean!).
* Copy the files headers of Freeglut (/include/gl) into the Cygwin directory
/usr/include/Gl.
* Copy the files headers (always /include/gl) into /usr/include/mingw/Gl:
this is used for compilations with the flag - mno-cygwin, which uses the
includes in mingw.
o You may need to erase the old GLUT include files if you installed it
with Cygwin.
Use of the library
* We will test with the program shapes, found in progs/demonstrations/shapes
o -mno-cygwin is used to force the use of Mingw without the large
dependence cygwin1.dll.
o -mwindows is only used to remove the horrible Shell window (very
useful for the settling, on the other hand).
o -L. (note the period after the "L"): I left libfreeglut.a,
libfreeglutdll.a and freeglut.dll in the test directory, at the time
of the tests.
Compilation of the static freeglut library, without cygwin
* All the simplicity lies in the define: -DFREEGLUT_STATIC
o It serves to obtain good decoration of the function names in the
imports of the lib Freeglut.
o You can test without and use a hex editor to see the differences
in the objects.
* attention with the order of the libraries: -lfreeglut (static) must be
before the declaration of the dynamic libraries.
* gcc shapes.c -L. -lfreeglut -lopengl32 -lwinmm -lgdi32 -mno-cygwin -mwindows -DFREEGLUT_STATIC
Compilation with DLL freeglut, without cygwin
* For the define, see the notices above
* The order of the libraries is no longer important.
* gcc shapes.c -L. -lopengl32 -lwinmm -lgdi32 -lfreeglut -mno-cygwin -DFREEGLUT_STATIC
Compilation with DLL freeglut, Cygwin
* This example is given only for reference, the topic of this ticket being
to get rid of Cygwin.
o Let us say that can be used to make the point (and later).
* gcc shapes.c -L. -lopengl32 -lwinmm -lgdi32 -lfreeglut
Where are the dooooocs?
* Freeglut is delivered with its documentation, more very up to date.
o It seems that there is a problem with the original GLUT
documentation. Not only it does not correspond completely to the
operation of Freeglut, but moreover, its author (Mark Kilgard)
copyrighted it. Its distribution is thus difficult.
* Jocelyn Fréchot undertook a levelling of the docs for version 2.6.0. One can find them on his site for the moment:
o http://jocelyn.frechot.free.fr/freeglut/
Something survived...
* I also tested the recompiling of the demonstrations of the original lib
GLUT (peace with its ashes).
o Nothing in particular to be announced.
* Thank you with all the courageous maintainers for Freeglut, that one
believed dead, but which still move.

48
README.macosx Normal file
View File

@ -0,0 +1,48 @@
Freeglut on MacOS X
===================
Currently freeglut does not support the native Cocoa API and the OpenGL
framework which works with it, but rather relies on X11 (XQuartz) and the Mesa
OpenGL and GLX libraries.
The simplest way to set up the prerequisites for building and using freeglut is
with the homebrew package management system: https://brew.sh
Build instructions
------------------
Prerequisites:
- If you don't already have homebrew, go to https://brew.sh and follow their
instructions.
- If you don't already have a compiler toolchain installed, download the Xcode
commandline tools from the apple store and install them first.
- If you don't have XQuartz installed, get it from https://www.xquartz.org
- Use homebrew to install cmake, and all the necessary libraries:
`brew install cmake libx11 libxi libxrandr libxxf86vm pkg-config mesa`
Build freeglut:
- Create a build directory under the freeglut directory and change into it:
`mkdir build && cd build`
- Run cmake to generate the makefile:
`cmake -DFREEGLUT_BUILD_DEMOS=OFF -DOPENGL_gl_LIBRARY=/usr/local/lib/libGL.dylib ..`
- Run `make` to build freeglut, and `make install` to install it.
Usage
-----
To use freeglut in your program **do not** include `<GLUT/glut.h>`; that header
is part of Apple's GLUT framework. Use `#include <GL/glut.h>` instead as usual,
or `#include <GL/freeglut.h>` if you wish to take advantage of the extended
freeglut API.
Similarly, to link with freeglut **do not** use `-framework GLUT` in your
linker command line. Instead use the standard `-lglut` argument, as you would
on any other UNIX system.
Known issues
------------
Some versions of XQuartz do not map the option keys to ALT by default, making
it impossible to get the `GLUT_ACTIVE_ALT` bit set in the bitmask returned by
`glutGetModifiers`. To change this behavior go to the XQuartz preferences and
enable the "Option keys send Alt_L and Alt_R" checkbox in the "input" tab.

97
README.md Normal file
View File

@ -0,0 +1,97 @@
freeglut
========
![GNU/Linux (X11) build status](https://github.com/FreeGLUTProject/freeglut/actions/workflows/build_gnulinux_x11.yml/badge.svg)
![Windows build status](https://github.com/FreeGLUTProject/freeglut/actions/workflows/build_win_msvc.yml/badge.svg)
![MacOS X (X11) build status](https://github.com/FreeGLUTProject/freeglut/actions/workflows/build_macosx_x11.yml/badge.svg)
OVERVIEW
--------
Freeglut, the Free OpenGL Utility Toolkit, is meant to be a free alternative to
Mark Kilgard's GLUT library. Freeglut is free software, distributed under an
MIT/X11 style license. You are free to use, modify, and redistribute freeglut
with or without modifications (see COPYING for details).
In short, freeglut can be used by OpenGL programs to perform those tasks which
would normally require platform-specific code. Tasks like creating a window,
creating an OpenGL context and binding it to the window, and processing input
events. Freeglut provides a concise and elegant API to handle those tasks, in a
platform-independent manner, keeping the application simple and portable.
One of the main goals of freeglut, is maximum compatibility. Freeglut is both
source and binary-compatible with the original GLUT, and can be used as a
drop-in replacement for it. We take great care to maintain a stable API and ABI,
and to introduce any new features and improvements in a way which does not
compromise compatibility.
Freeglut can be used with a wide range of OpenGL implementations, from the very
early OpenGL 1.0 on SGI computers, to the very latest modern OpenGL versions on
current GPUs. It can be used to create a classic OpenGL context, or a versioned
core profile or compatibility context. Freeglut can also be used with OpenGL ES,
on desktop or mobile devices.
PORTS
-----
Currently supported platforms:
- UNIX systems with X11 or Wayland (such as GNU/Linux, FreeBSD, IRIX, etc)
- MS Windows
- macOS with XQuartz (no native Cocoa support yet)
- Android (NDK)
- BlackBerry
Consult the platform-specific readme files for details on the level of support
and build instructions.
INSTALLATION
------------
Freeglut relies on cmake (minimum 3.0.0) to generate build files for all the
different supported platforms and toolchains.
See [`README.cmake`](README.cmake) as a starting point, as well as the other `README`
files for further info.
For those cases where using cmake is inconvenient, we also provide a set of
unofficial, unsupported, possibly unmaintained, but potentially useful,
alternative build files. See [`altbuild/README.md`](altbuild/README.md) for details.
CONTRIBUTING
------------
Patches and pull requests for bugfixes and new features are certainly welcome.
Please send patches to the freeglut-developer mailing list (see CONTACT below).
Feel free to report any bugs you encounter, using the github *issues* system.
Older bug reports and feature requests are still reachable on:
- https://sourceforge.net/p/freeglut/bugs/
- https://sourceforge.net/p/freeglut/feature-requests/
But you are encouraged to use github issues for new ones.
Alternatively you can also send bug reports and feature requests to the
freeglut-developer mailing list if you prefer. Extended discussions about new
features and design issues for large contributions, are best suited to the
mailing list.
CONTACT
-------
FreeGLUT website: http://freeglut.sourceforge.net
FreeGLUT mailing lists:
- developer: https://lists.sourceforge.net/lists/listinfo/freeglut-developer
- bugs: https://lists.sourceforge.net/lists/listinfo/freeglut-bugs
- announce: https://lists.sourceforge.net/lists/listinfo/freeglut-announce
You need to subscribe before posting to any of our mailing lists. Make sure
to avoid selecting "daily digest mode" if you intend to post, so that you can
reply properly to specific messages. Also, please do not top-post, and try to
send properly formated emails (text, hard-wrapped at 72 columns, no binary or
large attachements).

49
README.mingw_cross Normal file
View File

@ -0,0 +1,49 @@
Cross-compilation from GNU/Linux (static and shared DLL)
========================================================
Install MinGW, and specify which MinGW you're using:
- on Debian/Ubuntu, mingw-w64, 64-bit executables:
apt-get install mingw-w64
GNU_HOST=x86_64-w64-mingw32
- on Debian/Ubuntu, mingw-w64, 32-bit executables:
apt-get install mingw-w64
GNU_HOST=i686-w64-mingw32
- on Fedora, mingw32, 32-bit executables:
yum install mingw32-gcc
GNU_HOST=i686-pc-mingw32
- on Debian/Ubuntu, mingw32 (deprecated):
apt-get install mingw32
GNU_HOST=i586-mingw32msvc
With CMake
----------
Cross-compile with:
mkdir cross-woe/ && cd cross-woe/
cmake \
-D GNU_HOST=$GNU_HOST \
-D CMAKE_TOOLCHAIN_FILE=mingw_cross_toolchain.cmake \
-D CMAKE_INSTALL_PREFIX=/freeglut \
..
make -j4
make install DESTDIR=$(pwd)
Everything is now in the new 'freeglut/' directory.
The .dll is in 'freeglut/lib/'.
Compiling your code
-------------------
Compilation of your own programs is done as usual.
See README.cygwin_mingw for details.

91
README.win32 Normal file
View File

@ -0,0 +1,91 @@
NB
==================================
For ancient 16bit compatibility, windef.h (included through windows.h in
freeglut_std.h) defines near and far. Its best to avoid using variables
with these names in your own program.
Installing the Libraries with MSVC
==================================
To install "freeglut" on your system so that your other projects will see it,
you will need to copy various files to various locations.
- The header files "freeglut.h", "freeglut_ext.h", "freeglut_std.h", and
"glut.h" (distributed in the directory "freeglut\freeglut\include\GL")
need to be copied to a "GL" directory under the MSVC include directory.
The MSVC include directory generally has a path similar to
"C:\Program Files\Microsoft Visual Studio\VC98\Include"
The "GL" subdirectory under that will probably already have the header
files "gl.h", "glaux.h", and "glu.h".
- The library file "freeglut.lib" or "freeglut_static.lib" (from the
corresponding debug or release directory) needs to be copied into the
MSVC library directory. This usually has a path similar to:
"%ProgramFiles%\Microsoft SDKs\Windows\v7.0A\Lib" - x86 32 bits LIB's
"%ProgramFiles(x86)%\Microsoft SDKs\Windows\v7.0A\Lib" - x64 32 bits LIB's
"%ProgramFiles(x86)%\Microsoft SDKs\Windows\v7.0A\Lib\x64" - x64 64 bits LIB's
Note that there is no "GL" subdirectory here. This directory should
already have the files "opengl32.lib", "glu32.lib", and "glaux.lib".
- If you are using the DLL version of "freeglut", the file "freeglut.dll"
needs to be copied from the Debug or the Release directory into the
DLL directory. This usually has a path similar to
"%SystemRoot%\System32\" - x86 32 bits DLL's
"%SystemRoot%\SysWOW64\" - x64 32 bits DLL's
"%SystemRoot%\System32\" - x64 64 bits DLL's
and will probably already have the files "opengl32.dll" and "glu32.dll".
Building and Installing the Libraries with Open Watcom
======================================================
Start a command prompt and change directory to the freeglut installation
directory. Type "wmake -f Makefile.wat all" to build the DLL and static
libraries in both debug and release versions.
To install "freeglut" on your system so that your other projects will see it,
you will need to copy various files to various locations.
- The header files "freeglut.h", "freeglut_ext.h", "freeglut_std.h", and
"glut.h" (distributed in the directory "freeglut\freeglut\include\GL")
need to be copied to a "GL" directory under the Open Watcom 32-bit
Windows include directory. This usually has a path similar to
"C:\WATCOM\h\nt\GL"
- The library file "freeglut.lib" or "freeglut_static.lib" (from the
corresponding debug or release directory) needs to be copied into the
Open Watcom 32-bit Windows library directory. This usually has a path
similar to
"C:\WATCOM\lib386\nt"
- If you are using the DLL version of "freeglut", the file "freeglut.dll"
needs to be copied from the Debug or the Release directory into the
DLL directory. This usually has a path similar to
"C:\Windows\System32"
and will probably already have the files "opengl32.dll" and "glu32.dll".
Unlike the *nix release, the library names are NOT automatic replacements for
the GLUT library names. You may rename them manually if you wish, but this is
not necessary as the header file includes a pragma telling the compiler which
library file to look for.
Building and Installing the Libraries with Cygwin
=================================================
To build "freeglut" under Cygwin, you have two choices:
- You can build a normal Cygwin library, which depends on Cygwin's X11
libraries. To do this, you can just use the normal autotools incantation:
./configure && make install
- Alternatively, you can build a DLL which does not depend on X11 and links
against the opengl32 DLL. To do this, configure need a few more flags:
./configure CPPFLAGS=-mno-cygwin LDFLAGS=-mno-cygwin --without-x && make install
If you don't have MSVC, Open Watcom or Cygwin
=============================================
The "freeglut" developers' community discussed the possibility of distributing
binaries and decided against it. If you need Windows library files, please
contact John F. Fay at <john.fay@eglin.af.mil> or put a request on the
"freeglut" developers' mailing list <freeglut-developer@lists.sourceforge.net>.

76
altbuild/Makefile Normal file
View File

@ -0,0 +1,76 @@
# Simple UNIX makefile
# Builds freeglut as a static library.
# ------- options --------
# installation prefix
PREFIX = /usr/local
# subdirectory for libraries (lib, lib32, lib64?)
LIBDIR = lib
# optimization flags
opt = -O3
# debug symbols
#dbg = -g
# libraries to link when building the demo program (make demo). You might need
# to adjust these, depending on the choices in config.h
demo_libs = $(liba) -lGL -lX11 -lXmu -lXext -lXi -lXrandr -lXxf86vm -lm
# ---- end of options ----
coreobj = src/fg_gl2.o src/fg_misc.o src/fg_input_devices.o src/fg_ext.o \
src/fg_joystick.o src/fg_init.o src/fg_callbacks.o \
src/fg_menu.o src/fg_stroke_roman.o src/fg_structure.o src/fg_overlay.o \
src/fg_window.o src/fg_state.o src/fg_videoresize.o src/fg_spaceball.o \
src/fg_cursor.o src/fg_main.o src/fg_gamemode.o \
src/fg_stroke_mono_roman.o src/fg_geometry.o src/fg_font.o src/fg_display.o \
src/fg_font_data.o src/fg_teapot.o
x11obj = src/x11/fg_state_x11_glx.o src/x11/fg_glutfont_definitions_x11.o \
src/x11/fg_joystick_x11.o src/x11/fg_structure_x11.o src/x11/fg_cursor_x11.o \
src/x11/fg_state_x11.o src/x11/fg_main_x11.o src/x11/fg_spaceball_x11.o \
src/x11/fg_input_devices_x11.o src/x11/fg_ext_x11.o src/x11/fg_window_x11_glx.o \
src/x11/fg_gamemode_x11.o src/x11/fg_init_x11.o src/x11/fg_menu_x11.o \
src/x11/fg_xinput_x11.o src/x11/fg_window_x11.o src/x11/fg_display_x11_glx.o \
src/x11/fg_cmap_x11.o
obj = $(coreobj) $(x11obj)
liba = libglut.a
incpath = -I. -Isrc -Iinclude -I/usr/local/include -I/usr/X11R6/include
libpath = -L/usr/local/lib -L/usr/X11R6/lib
CFLAGS = -O2 $(incpath) -DHAVE_CONFIG_H
LDFLAGS = $(libpath)
$(liba): $(obj)
$(AR) rcs $@ $(obj)
demo: progs/demos/3dview/3dview.o $(liba)
$(CC) -o $@ progs/demos/3dview/3dview.o $(LDFLAGS) $(demo_libs)
.c.o:
$(CC) -o $@ $(CFLAGS) -c $<
.PHONY: clean
clean:
rm -f $(obj) $(liba) demo
.PHONY: install
install: $(liba)
mkdir -p $(DESTDIR)$(PREFIX)/$(LIBDIR) $(DESTDIR)$(PREFIX)/include/GL
cp include/GL/* $(DESTDIR)$(PREFIX)/include/GL
cp $(liba) $(DESTDIR)$(PREFIX)/$(LIBDIR)/$(liba)
.PHONY: uninstall
uninstall:
rm -f $(DESTDIR)$(PREFIX)/$(LIBDIR)/$(liba)
rm -f $(DESTDIR)$(PREFIX)/include/GL/glut.h
rm -f $(DESTDIR)$(PREFIX)/include/GL/freeglut.h
rm -f $(DESTDIR)$(PREFIX)/include/GL/freeglut_std.h
rm -f $(DESTDIR)$(PREFIX)/include/GL/freeglut_ext.h
rm -f $(DESTDIR)$(PREFIX)/include/GL/freeglut_ucall.h

66
altbuild/README.md Normal file
View File

@ -0,0 +1,66 @@
Simple build files for freeglut
===============================
This directory includes a number of simple ways to build freeglut, without
relying on extra tools.
The official build system used by freeglut is cmake, with the current minimum
cmake version required being set to 3.0. Installing and using cmake 3.0 or later
to generate build files might be difficult or inconvenient in some cases.
Installing modern versions of cmake on very old UNIX systems might be difficult
or impossible. And finding the exact cmake version which still supports
generating project files for a certain old IDE, dropped from current cmake, can
be annoying.
None of the files in this directory are officially supported! Some of them might
be completely unmaintained, broken, or out of date. Please report any issues,
but be warned that you may have to fix them yourself.
The simple build files in this directory do not build the demo programs, and do
not provide the same flexibility of build options as the official cmake build.
Most of them just build a default configuration of freeglut as a static library
and that's it.
Configuration
-------------
Before using any of these build files, first you'll need to select one of the
`config.h.*` files provided, copy it to the project root directory with the name
`config.h`. The following config files are available:
- config.h.unix: Modern UNIX with X11 (GNU/Linux, FreeBSD, etc).
- config.h.msvc6: Windows build with MS Visual C/C++ 6.0.
- config.h.irix5: IRIX 5.x build with the SGI compiler.
- config.h.irix6: IRIX 6.x build with the SGI compiler.
You can edit the `config.h` file to remove unnecessary dependencies (and their
corresponding features). For example, some old X servers do not have the XRandR
extension, or you may not wish to install libXrandr, in which case you should
disable it by deleting the `#define HAVE_X11_EXTENSIONS_XRANDR_H` line, or
changing `define` to `undef`.
Simple UNIX Makefile
--------------------
This should build freeglut on many different UNIX systems with their native
make utility.
- Copy `Makefile` to the project root directory.
- Copy the appropriate `config.h.*` file to the project root directory renamed
to `config.h`.
- `make` to build.
- `make install` to install. Change the `PREFIX` variable at the top of the
`Makefile` to change the installation prefix.
You can also attempt to build a simple statically linked demo program, by typing
`make demo`. But be warned that you might need to modify the `demo_libs`
variable at the top of the `Makefile` to adjust for whatever options are
selected in the `config.h` you used to build freeglut.
MS Visual Studio 6.0 project
----------------------------
Project files for building freeglut on 32bit windows, using MSVC6.
- Copy `config.h.msvc6` to the project root directory renamed to `config.h`.
- Open the `freeglut.dsw` "workspace" file with visual studio 6.
- Select build all from the build menu.
The MSVC6 project builds freeglut as both a static library and a DLL, and also
builds a simple statically linked demo program.

23
altbuild/config.h.irix5 Normal file
View File

@ -0,0 +1,23 @@
/* freeglut configuration file for building on SGI IRIX 5.x
*
* #define to enable, #undef or delete line to disable
*
* Copy to the freeglut root directory as config.h along with altbuild/Makefile
*/
#define HAVE_SYS_TYPES_H
#define HAVE_UNISTD_H
#define HAVE_SYS_TIME_H
#define HAVE_SYS_PARAM_H
#define HAVE_SYS_IOCTL_H
#define HAVE_FCNTL_H
#define HAVE_ERRNO_H
#define HAVE_GETTIMEOFDAY
#define HAVE_VFPRINTF
#define HAVE_ULONG_LONG
/* inttypes.h conflicts with sys/types.h */
#undef HAVE_INTTYPES_H
/* warning and errors printed? */
#define FREEGLUT_PRINT_WARNINGS
#define FREEGLUT_PRINT_ERRORS

35
altbuild/config.h.irix6 Normal file
View File

@ -0,0 +1,35 @@
/* freeglut configuration file for IRIX 6.x (tested 6.5.26)
*
* #define to enable, #undef or delete line to disable
*
* Copy to the freeglut root directory as config.h along with altbuild/Makefile
*/
/* warning and errors printed? */
#define FREEGLUT_PRINT_WARNINGS
#define FREEGLUT_PRINT_ERRORS
/* all of these should be available on relatively modern UNIX systems */
#define HAVE_SYS_TYPES_H /* sys/types.h */
#define HAVE_UNISTD_H /* unistd.h */
#define HAVE_SYS_TIME_H /* sys/time.h */
#define HAVE_SYS_PARAM_H /* sys/param.h */
#define HAVE_SYS_IOCTL_H /* sys/ioctl.h */
#define HAVE_FCNTL_H /* fcntl.h */
#define HAVE_ERRNO_H /* errno.h */
#define HAVE_GETTIMEOFDAY /* gettimeofday() */
#define HAVE_VFPRINTF /* vfprintf() */
#define HAVE_INTTYPES_H /* inttypes.h */
#define HAVE_ULONG_LONG /* unsigned long long */
#undef HAVE_STDINT_H /* stdint.h - not available with MIPSpro cc */
/* don't need, XParseGeometry is in libX11 */
#undef NEED_XPARSEGEOMETRY_IMPL
/* __int64 fallback is for msvc */
#undef HAVE_U__INT64
/* SGI X server does not support xf86vm, xrandr, and xinput2 */
#undef HAVE_X11_EXTENSIONS_XF86VMODE_H
#undef HAVE_X11_EXTENSIONS_XRANDR_H
#undef HAVE_X11_EXTENSIONS_XINPUT2_H
/* USB HID, is only needed needed for joystick on BSD */
#undef HAVE_USBHID_H

14
altbuild/config.h.msvc6 Normal file
View File

@ -0,0 +1,14 @@
/* freeglut configuration file for Windows with MS Visual C 6.0
*
* Copy to the freeglut root dir as config.h, and open altbuild/freeglut.dsw
* Do not move the dsw/dsp project files, leave them in altbuild.
*/
#define HAVE_SYS_TYPES_H
#define HAVE_FCNTL_H
#define HAVE_ERRNO_H
#define NEED_XPARSEGEOMETRY_IMPL
#define HAVE_U__INT64
/* warning and errors printed? */
#define FREEGLUT_PRINT_WARNINGS
#define FREEGLUT_PRINT_ERRORS

37
altbuild/config.h.unix Normal file
View File

@ -0,0 +1,37 @@
/* freeglut configuration file for GNU/Linux and BSD
*
* #define to enable, #undef or delete line to disable
*
* Copy to the freeglut root directory as config.h along with altbuild/Makefile
*/
/* XFree86 Video Mode extension, used for game mode, requires libXxf86vm */
#define HAVE_X11_EXTENSIONS_XF86VMODE_H
/* XR&R extension, used for game mode, requires libXrandr */
#define HAVE_X11_EXTENSIONS_XRANDR_H
/* XInput2 extension, used for joystick input, requires libXi */
#define HAVE_X11_EXTENSIONS_XINPUT2_H
/* USB HID, needed for joystick on BSD, requires libusbhid */
#define HAVE_USBHID_H
/* warning and errors printed? */
#define FREEGLUT_PRINT_WARNINGS
#define FREEGLUT_PRINT_ERRORS
/* all of these should be available on relatively modern UNIX systems */
#define HAVE_SYS_TYPES_H /* sys/types.h */
#define HAVE_UNISTD_H /* unistd.h */
#define HAVE_SYS_TIME_H /* sys/time.h */
#define HAVE_SYS_PARAM_H /* sys/param.h */
#define HAVE_SYS_IOCTL_H /* sys/ioctl.h */
#define HAVE_FCNTL_H /* fcntl.h */
#define HAVE_ERRNO_H /* errno.h */
#define HAVE_GETTIMEOFDAY /* gettimeofday() */
#define HAVE_VFPRINTF /* vfprintf() */
#define HAVE_STDINT_H /* stdint.h - might not be available, undef if not found */
#define HAVE_INTTYPES_H /* inttypes.h */
#define HAVE_ULONG_LONG /* unsigned long long */
/* don't need, XParseGeometry is in libX11 */
#undef NEED_XPARSEGEOMETRY_IMPL
/* __int64 fallback is for msvc */
#undef HAVE_U__INT64

102
altbuild/demo.dsp Normal file
View File

@ -0,0 +1,102 @@
# Microsoft Developer Studio Project File - Name="demo" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=demo - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "demo.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "demo.mak" CFG="demo - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "demo - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "demo - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "demo - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I "../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "FREEGLUT_STATIC" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"Release"
!ELSEIF "$(CFG)" == "demo - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "FREEGLUT_STATIC" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"Debug"
!ENDIF
# Begin Target
# Name "demo - Win32 Release"
# Name "demo - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\progs\demos\3dview\3dview.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

318
altbuild/freeglut.dsp Normal file
View File

@ -0,0 +1,318 @@
# Microsoft Developer Studio Project File - Name="freeglut" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=freeglut - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "freeglut.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "freeglut.mak" CFG="freeglut - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "freeglut - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "freeglut - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "freeglut - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FREEGLUT_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /I "../include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FREEGLUT_EXPORTS" /D "HAVE_CONFIG_H" /D _WIN32_WINNT=0x0500 /D WINVER=0x0500 /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
!ELSEIF "$(CFG)" == "freeglut - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FREEGLUT_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I ".." /I "../include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FREEGLUT_EXPORTS" /D "HAVE_CONFIG_H" /D _WIN32_WINNT=0x0500 /D WINVER=0x0500 /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"Debug/freeglutd.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "freeglut - Win32 Release"
# Name "freeglut - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\config.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_callback_macros.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_callbacks.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_cmap_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_cursor.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_cursor_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_display.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_display_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_ext.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_ext_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_font.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_font_data.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_gamemode.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_gamemode_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_geometry.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_gl2.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_gl2.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_init.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_init.h
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_init_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_input_devices.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_input_devices_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_internal.h
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_internal_mswin.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_joystick.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_joystick_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_main.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_main_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_menu.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_menu_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_misc.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_overlay.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_spaceball.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_spaceball_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_state.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_state_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_stroke_mono_roman.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_stroke_roman.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_structure.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_structure_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_teapot.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_teapot_data.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_version.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_videoresize.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_window.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_window_mswin.c
# End Source File
# Begin Source File
SOURCE=.\freeglutdll.def
# End Source File
# Begin Source File
SOURCE=..\src\util\xparsegeometry_repl.c
# End Source File
# Begin Source File
SOURCE=..\src\util\xparsegeometry_repl.h
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\include\Gl\freeglut.h
# End Source File
# Begin Source File
SOURCE=..\include\Gl\freeglut_ext.h
# End Source File
# Begin Source File
SOURCE=..\include\Gl\freeglut_std.h
# End Source File
# Begin Source File
SOURCE=..\include\Gl\freeglut_ucall.h
# End Source File
# Begin Source File
SOURCE=..\include\Gl\glut.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

59
altbuild/freeglut.dsw Normal file
View File

@ -0,0 +1,59 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "demo"=.\demo.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name freeglut_static
End Project Dependency
Begin Project Dependency
Project_Dep_Name freeglut
End Project Dependency
}}}
###############################################################################
Project: "freeglut"=.\freeglut.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "freeglut_static"=.\freeglut_static.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,304 @@
# Microsoft Developer Studio Project File - Name="freeglut_static" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=freeglut_static - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "freeglut_static.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "freeglut_static.mak" CFG="freeglut_static - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "freeglut_static - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "freeglut_static - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "freeglut_static - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release_static"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release_static"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /I ".." /I "../include" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "FREEGLUT_STATIC" /D "HAVE_CONFIG_H" /D _WIN32_WINNT=0x0500 /D WINVER=0x0500 /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "freeglut_static - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug_static"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug_static"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I ".." /I "../include" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "FREEGLUT_STATIC" /D "HAVE_CONFIG_H" /D _WIN32_WINNT=0x0500 /D WINVER=0x0500 /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"Debug\freeglut_staticd.lib"
!ENDIF
# Begin Target
# Name "freeglut_static - Win32 Release"
# Name "freeglut_static - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=..\config.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_callback_macros.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_callbacks.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_cmap_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_cursor.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_cursor_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_display.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_display_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_ext.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_ext_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_font.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_font_data.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_gamemode.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_gamemode_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_geometry.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_gl2.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_gl2.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_init.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_init.h
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_init_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_input_devices.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_input_devices_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_internal.h
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_internal_mswin.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_joystick.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_joystick_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_main.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_main_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_menu.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_menu_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_misc.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_overlay.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_spaceball.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_spaceball_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_state.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_state_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_stroke_mono_roman.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_stroke_roman.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_structure.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_structure_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_teapot.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_teapot_data.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_version.h
# End Source File
# Begin Source File
SOURCE=..\src\fg_videoresize.c
# End Source File
# Begin Source File
SOURCE=..\src\fg_window.c
# End Source File
# Begin Source File
SOURCE=..\src\mswin\fg_window_mswin.c
# End Source File
# Begin Source File
SOURCE=..\src\util\xparsegeometry_repl.c
# End Source File
# Begin Source File
SOURCE=..\src\util\xparsegeometry_repl.h
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=..\include\Gl\freeglut.h
# End Source File
# Begin Source File
SOURCE=..\include\Gl\freeglut_ext.h
# End Source File
# Begin Source File
SOURCE=..\include\Gl\freeglut_std.h
# End Source File
# Begin Source File
SOURCE=..\include\Gl\freeglut_ucall.h
# End Source File
# Begin Source File
SOURCE=..\include\Gl\glut.h
# End Source File
# End Group
# End Target
# End Project

165
altbuild/freeglutdll.def Normal file
View File

@ -0,0 +1,165 @@
VERSION 3.4
EXPORTS
glutInit
glutInitWindowPosition
glutInitWindowSize
glutInitDisplayMode
glutInitDisplayString
glutMainLoop
glutMainLoopEvent
glutLeaveMainLoop
glutCreateWindow
glutCreateSubWindow
glutDestroyWindow
glutSetWindow
glutGetWindow
glutSetWindowData
glutGetWindowData
glutSetWindowTitle
glutSetIconTitle
glutReshapeWindow
glutPositionWindow
glutShowWindow
glutHideWindow
glutIconifyWindow
glutPushWindow
glutPopWindow
glutFullScreen
glutPostWindowRedisplay
glutPostRedisplay
glutSwapBuffers
glutWarpPointer
glutSetCursor
glutEstablishOverlay
glutRemoveOverlay
glutUseLayer
glutPostOverlayRedisplay
glutPostWindowOverlayRedisplay
glutShowOverlay
glutHideOverlay
glutCreateMenu
glutDestroyMenu
glutGetMenu
glutSetMenu
glutGetMenuData
glutSetMenuData
glutAddMenuEntry
glutAddSubMenu
glutChangeToMenuEntry
glutChangeToSubMenu
glutRemoveMenuItem
glutAttachMenu
glutDetachMenu
glutTimerFunc
glutIdleFunc
glutKeyboardFunc
glutSpecialFunc
glutReshapeFunc
glutPositionFunc
glutVisibilityFunc
glutDisplayFunc
glutMouseFunc
glutMouseWheelFunc
glutMotionFunc
glutPassiveMotionFunc
glutEntryFunc
glutCloseFunc
glutWMCloseFunc
glutKeyboardUpFunc
glutSpecialUpFunc
glutJoystickFunc
glutMenuStateFunc
glutMenuStatusFunc
glutMenuDestroyFunc
glutOverlayDisplayFunc
glutWindowStatusFunc
glutSpaceballMotionFunc
glutSpaceballRotateFunc
glutSpaceballButtonFunc
glutButtonBoxFunc
glutDialsFunc
glutTabletMotionFunc
glutTabletButtonFunc
glutSetOption
glutGet
glutDeviceGet
glutGetModifiers
glutLayerGet
glutBitmapCharacter
glutBitmapWidth
glutStrokeCharacter
glutStrokeWidth
glutBitmapLength
glutStrokeLength
glutBitmapHeight
glutStrokeHeight
glutBitmapString
glutStrokeString
glutWireCube
glutSolidCube
glutWireSphere
glutSolidSphere
glutWireCone
glutSolidCone
glutWireTorus
glutSolidTorus
glutWireDodecahedron
glutSolidDodecahedron
glutWireOctahedron
glutSolidOctahedron
glutWireTetrahedron
glutSolidTetrahedron
glutWireIcosahedron
glutSolidIcosahedron
glutWireRhombicDodecahedron
glutSolidRhombicDodecahedron
glutWireSierpinskiSponge
glutSolidSierpinskiSponge
glutWireTeapot
glutSolidTeapot
glutWireTeacup
glutSolidTeacup
glutWireTeaspoon
glutSolidTeaspoon
glutWireCylinder
glutSolidCylinder
glutGameModeString
glutEnterGameMode
glutLeaveGameMode
glutGameModeGet
glutVideoResizeGet
glutSetupVideoResizing
glutStopVideoResizing
glutVideoResize
glutVideoPan
glutSetColor
glutGetColor
glutCopyColormap
glutIgnoreKeyRepeat
glutSetKeyRepeat
glutForceJoystickFunc
glutExtensionSupported
glutReportErrors
glutGetProcAddress
glutExit
glutFullScreenToggle
glutLeaveFullScreen
glutSetMenuFont
glutGetModeValues
glutInitContextFlags
glutInitContextVersion
glutInitContextProfile
glutInitErrorFunc
glutInitWarningFunc
__glutInitWithExit
__glutCreateWindowWithExit
__glutCreateMenuWithExit
glutMultiButtonFunc
glutMultiEntryFunc
glutMultiMotionFunc
glutMultiPassiveFunc
glutInitContextFunc
glutAppStatusFunc
glutSetVertexAttribCoord3
glutSetVertexAttribNormal
glutSetVertexAttribTexCoord2

9
android/Android.mk Normal file
View File

@ -0,0 +1,9 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := freeglut-gles
LOCAL_SRC_FILES := lib/libfreeglut-gles.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)

2
android/README Normal file
View File

@ -0,0 +1,2 @@
- Android.mk : used to create a module compatible with the NDK build
system. See ../README.android for details.

6
android_toolchain.cmake Normal file
View File

@ -0,0 +1,6 @@
# CMake toolchain file, cf. README.android
SET(CMAKE_SYSTEM_NAME Linux) # Tell CMake we're cross-compiling
include(CMakeForceCompiler)
# Prefix detection only works with compiler id "GNU"
CMAKE_FORCE_C_COMPILER(arm-linux-androideabi-gcc GNU)
SET(ANDROID TRUE)

244
blackberry.toolchain.cmake Normal file
View File

@ -0,0 +1,244 @@
# ------------------------------------------------------------------------------
# BlackBerry CMake toolchain file, for use with the BlackBerry 10 NDK
# Requires cmake 2.6.3 or newer (2.8.3 or newer is recommended).
#
# Usage Linux:
# $ source /absolute/path/to/the/bbndk/bbndk-env.sh
# $ mkdir build
# $ cd build
# $ cmake .. -DCMAKE_TOOLCHAIN_FILE="../blackberry.toolchain.cmake" -DBLACKBERRY_ARCHITECTURE=arm -DFREEGLUT_GLES=ON -DFREEGLUT_BUILD_DEMOS=NO -DCMAKE_VERBOSE_MAKEFILE=TRUE -G "Eclipse CDT4 - Unix Makefiles"
# $ make -j8
#
# Usage Mac:
# Same as the steps on Linux
#
# Usage Windows:
# > /absolute/path/to/the/bbndk/bbndk-env.bat
# > mkdir build
# > cd build
# > cmake .. -DCMAKE_TOOLCHAIN_FILE="../blackberry.toolchain.cmake" -DBLACKBERRY_ARCHITECTURE=arm -DFREEGLUT_GLES=ON -DFREEGLUT_BUILD_DEMOS=NO -DCMAKE_VERBOSE_MAKEFILE=TRUE -G "Eclipse CDT4 - Unix Makefiles"
# > make -j8
#
cmake_minimum_required( VERSION 2.6.3 )
if( DEFINED CMAKE_CROSSCOMPILING )
# Subsequent toolchain loading is not really needed
return()
endif()
set( BLACKBERRY_TOOLCHAIN_ROOT "$ENV{QNX_HOST}" )
set( BLACKBERRY_TARGET_ROOT "$ENV{QNX_TARGET}" )
set( CMAKE_SYSTEM_NAME Linux )
set( CMAKE_SYSTEM_VERSION 1 )
# Check for PlayBook
if( EXISTS "${BLACKBERRY_TARGET_ROOT}/x86/lib/gcc/4.4.2" )
set( PLAYBOOK True )
endif()
# Check for for GCC 4.8.2
if( EXISTS "${BLACKBERRY_TARGET_ROOT}/x86/lib/gcc/4.8.2" )
set( BB_GCC_482 True )
endif()
# STL version: by default gnustl_static will be used
set( BLACKBERRY_USE_STLPORT FALSE CACHE BOOL "Experimental: use stlport_static instead of gnustl_static")
mark_as_advanced( BLACKBERRY_USE_STLPORT )
# Detect host platform
set( TOOL_OS_SUFFIX "" )
if( CMAKE_HOST_APPLE )
set( BLACKBERRY_NDK_HOST_SYSTEM_NAME "darwin-x86" )
elseif( CMAKE_HOST_WIN32 )
set( BLACKBERRY_NDK_HOST_SYSTEM_NAME "windows" )
set( TOOL_OS_SUFFIX ".exe" )
elseif( CMAKE_HOST_UNIX )
set(BLACKBERRY_NDK_HOST_SYSTEM_NAME "linux-x86" )
else()
message( FATAL_ERROR "Cross-compilation on your platform is not supported by this cmake toolchain" )
endif()
# Specify the cross compiler
set( CMAKE_C_COMPILER "$ENV{QNX_HOST}/usr/bin/qcc${TOOL_OS_SUFFIX}" CACHE PATH "gcc" )
set( CMAKE_CXX_COMPILER "$ENV{QNX_HOST}/usr/bin/qcc${TOOL_OS_SUFFIX}" CACHE PATH "g++" )
set( CMAKE_ASM_COMPILER "$ENV{QNX_HOST}/usr/bin/qcc${TOOL_OS_SUFFIX}" CACHE PATH "Assembler" )
if( CMAKE_VERSION VERSION_LESS 2.8.5 )
set( CMAKE_ASM_COMPILER_ARG1 "-c" )
endif()
# There may be a way to make cmake reduce these TODO
if( BLACKBERRY_ARCHITECTURE STREQUAL "arm" )
set( NEUTRINO_ARCH "v7" )
else()
set( NEUTRINO_ARCH "" )
endif()
set( CMAKE_STRIP "$ENV{QNX_HOST}/usr/bin/nto${BLACKBERRY_ARCHITECTURE}-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip" )
set( CMAKE_AR "$ENV{QNX_HOST}/usr/bin/nto${BLACKBERRY_ARCHITECTURE}-ar${TOOL_OS_SUFFIX}" CACHE PATH "archive" )
set( CMAKE_LINKER "$ENV{QNX_HOST}/usr/bin/nto${BLACKBERRY_ARCHITECTURE}${NEUTRINO_ARCH}-ld${TOOL_OS_SUFFIX}" CACHE PATH "linker" )
set( CMAKE_NM "$ENV{QNX_HOST}/usr/bin/nto${BLACKBERRY_ARCHITECTURE}${NEUTRINO_ARCH}-nm${TOOL_OS_SUFFIX}" CACHE PATH "nm" )
set( CMAKE_OBJCOPY "$ENV{QNX_HOST}/usr/bin/nto${BLACKBERRY_ARCHITECTURE}${NEUTRINO_ARCH}-objcopy${TOOL_OS_SUFFIX}" CACHE PATH "objcopy" )
set( CMAKE_OBJDUMP "$ENV{QNX_HOST}/usr/bin/nto${BLACKBERRY_ARCHITECTURE}${NEUTRINO_ARCH}-objdump${TOOL_OS_SUFFIX}" CACHE PATH "objdump" )
set( CMAKE_RANLIB "$ENV{QNX_HOST}/usr/bin/nto${BLACKBERRY_ARCHITECTURE}-ranlib${TOOL_OS_SUFFIX}" CACHE PATH "ranlib" )
# Installer
#if( APPLE )
# find_program( CMAKE_INSTALL_NAME_TOOL NAMES install_name_tool )
# if( NOT CMAKE_INSTALL_NAME_TOOL )
# message( FATAL_ERROR "Could not find install_name_tool, please check your #installation." )
# endif()
# mark_as_advanced( CMAKE_INSTALL_NAME_TOOL )
# endif()
# Setup output directories
set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" )
set( CMAKE_INSTALL_PREFIX "${BLACKBERRY_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" )
if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" )
set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" )
else()
set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" )
endif()
# Includes
if( PLAYBOOK )
list( APPEND BLACKBERRY_SYSTEM_INCLUDE_DIRS "${BLACKBERRY_TARGET_ROOT}/usr/include" )
else()
list( APPEND BLACKBERRY_SYSTEM_INCLUDE_DIRS "${BLACKBERRY_TARGET_ROOT}/qnx6/usr/include" )
endif()
# Flags and preprocessor definitions
set( BB_USING_GCC_482 False )
if( PLAYBOOK )
set( BLACKBERRY_COMP_DEF "-D__PLAYBOOK__" )
set( BLACKBERRY_COMP_VERSION "4.4.2" )
else()
set( BLACKBERRY_COMP_DEF "-D__QNX__" )
if( BB_GCC_482 AND BLACKBERRY_USE_GCC_4_8 )
set( BLACKBERRY_COMP_VERSION "4.8.2" )
set( BB_USING_GCC_482 True )
else()
set( BLACKBERRY_COMP_VERSION "4.6.3" )
endif()
endif()
if( BLACKBERRY_ARCHITECTURE STREQUAL "arm" )
set( BLACKBERRY_COMP_TARGET "gcc_ntoarmv7le" )
else()
set( BLACKBERRY_COMP_TARGET "gcc_ntox86" )
endif()
set( BLACKBERRY_CXX_COMP_LIB "" )
if( BLACKBERRY_DINKUM )
set( DINKUM 1 )
if( BB_USING_GCC_482 )
set( BLACKBERRY_COMP_TARGET "${BLACKBERRY_COMP_TARGET}_cpp" )
else()
set( BLACKBERRY_CXX_COMP_LIB "-Y_cpp" )
endif()
else()
set( DINKUM 0 )
if( BB_USING_GCC_482 )
set( BLACKBERRY_COMP_TARGET "${BLACKBERRY_COMP_TARGET}_gpp" )
else()
set( BLACKBERRY_CXX_COMP_LIB "-Y_gpp" )
endif()
endif()
set( BLACKBERRY_CC_FLAGS " -V${BLACKBERRY_COMP_VERSION},${BLACKBERRY_COMP_TARGET} ${BLACKBERRY_COMP_DEF}" )
set( BLACKBERRY_CXX_FLAGS " -V${BLACKBERRY_COMP_VERSION},${BLACKBERRY_COMP_TARGET} ${BLACKBERRY_CXX_COMP_LIB} ${BLACKBERRY_COMP_DEF}" )
set( BLACKBERRY 1 )
# NDK flags
if( DINKUM )
set( CMAKE_CXX_FLAGS "${BLACKBERRY_CXX_FLAGS} -DBLACKBERRY_DINKUM=1" )
set( CMAKE_C_FLAGS "${BLACKBERRY_CC_FLAGS} -DBLACKBERRY_DINKUM=1" )
else()
set( CMAKE_CXX_FLAGS "${BLACKBERRY_CXX_FLAGS}" )
set( CMAKE_C_FLAGS "${BLACKBERRY_CC_FLAGS}" )
endif()
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions" )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexceptions" )
# Release and Debug flags
if( BLACKBERRY_ARCHITECTURE STREQUAL "arm" )
set( CMAKE_CXX_FLAGS_RELEASE "-mthumb -O3" )
set( CMAKE_C_FLAGS_RELEASE "-mthumb -O3" )
set( CMAKE_CXX_FLAGS_DEBUG "-marm -Os -finline-limit=64" )
set( CMAKE_C_FLAGS_DEBUG "-marm -Os -finline-limit=64" )
else()
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=i486" )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=i486" )
endif()
# Cache flags
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" CACHE STRING "c++ flags" )
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "c flags" )
set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "c++ Release flags" )
set( CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}" CACHE STRING "c Release flags" )
set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "c++ Debug flags" )
set( CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}" CACHE STRING "c Debug flags" )
set( CMAKE_SHARED_LINKER_FLAGS "" CACHE STRING "linker flags" )
SET( CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "" CACHE STRING "linker flags")
SET( CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "" CACHE STRING "linker flags")
set( CMAKE_MODULE_LINKER_FLAGS "" CACHE STRING "linker flags" )
set( CMAKE_EXE_LINKER_FLAGS "-lstdc++" CACHE STRING "linker flags" )
# Finish flags
set( BLACKBERRY_CXX_FLAGS "${BLACKBERRY_CXX_FLAGS}" CACHE INTERNAL "Extra BlackBerry compiler flags")
set( BLACKBERRY_LINKER_FLAGS "${BLACKBERRY_LINKER_FLAGS}" CACHE INTERNAL "Extra BlackBerry linker flags")
set( CMAKE_CXX_FLAGS "${BLACKBERRY_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
set( CMAKE_C_FLAGS "${BLACKBERRY_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
# Global flags for cmake client scripts to change behavior
set( BLACKBERRY True )
# Find the Target environment
set( CMAKE_FIND_ROOT_PATH "${CMAKE_SOURCE_DIR}" "${BLACKBERRY_TARGET_ROOT}" "${CMAKE_INSTALL_PREFIX}" "${CMAKE_INSTALL_PREFIX}/share" )
# Search for libraries and includes in the ndk toolchain
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
# Macro to find packages on the host OS
macro( find_host_package )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER )
if( CMAKE_HOST_WIN32 )
SET( WIN32 1 )
SET( UNIX )
elseif( CMAKE_HOST_APPLE )
SET( APPLE 1 )
SET( UNIX )
endif()
find_package( ${ARGN} )
SET( WIN32 )
SET( APPLE )
SET( UNIX 1 )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
endmacro()
# Macro to find programs on the host OS
macro( find_host_program )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER )
if( CMAKE_HOST_WIN32 )
SET( WIN32 1 )
SET( UNIX )
elseif( CMAKE_HOST_APPLE )
SET( APPLE 1 )
SET( UNIX )
endif()
find_program( ${ARGN} )
SET( WIN32 )
SET( APPLE )
SET( UNIX 1 )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
endmacro()
# We are doing cross compiling, reset the OS information of the Building system
UNSET( APPLE )
UNSET( WIN32 )
UNSET( UNIX )

24
config.h.in Normal file
View File

@ -0,0 +1,24 @@
#cmakedefine HAVE_X11_EXTENSIONS_XF86VMODE_H
#cmakedefine HAVE_X11_EXTENSIONS_XRANDR_H
#cmakedefine HAVE_X11_EXTENSIONS_XINPUT2_H
#cmakedefine HAVE_SYS_TYPES_H
#cmakedefine HAVE_UNISTD_H
#cmakedefine HAVE_SYS_TIME_H
#cmakedefine HAVE_STDBOOL_H
#cmakedefine HAVE_SYS_PARAM_H
#cmakedefine HAVE_SYS_IOCTL_H
#cmakedefine HAVE_FCNTL_H
#cmakedefine HAVE_ERRNO_H
#cmakedefine HAVE_USBHID_H
#cmakedefine HAVE_GETTIMEOFDAY
#cmakedefine HAVE_VFPRINTF
#cmakedefine HAVE_DOPRNT
#cmakedefine NEED_XPARSEGEOMETRY_IMPL
#cmakedefine HAVE_STDINT_H
#cmakedefine HAVE_INTTYPES_H
#cmakedefine HAVE_ULONG_LONG
#cmakedefine HAVE_U__INT64
/* warning and errors printed? */
#cmakedefine FREEGLUT_PRINT_WARNINGS
#cmakedefine FREEGLUT_PRINT_ERRORS

10
freeglut.pc.in Normal file
View File

@ -0,0 +1,10 @@
prefix=@CMAKE_INSTALL_PREFIX@
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
includedir=${prefix}/include
Name: glut
Description: A freely licensed and improved alternative to the GLUT library
Version: @VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@
Libs: -L${libdir} -l@PC_LIBNAME@
Libs.private: @PC_LIBS_PRIVATE@
Cflags: -I${includedir} @PC_CFLAGS@

40
freeglut.rc.in Executable file
View File

@ -0,0 +1,40 @@
/* 0 ICON DISCARDABLE "OpenGL.ico" */
1 VERSIONINFO
FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,0
PRODUCTVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904b0"
BEGIN
/* VALUE "Comments", "\0" */
/* VALUE "CompanyName", "\0" */
VALUE "FileDescription", "Freeglut OpenGL Utility Toolkit\0"
VALUE "FileVersion", "@VERSION_MAJOR@, @VERSION_MINOR@, @VERSION_PATCH@, 0\0"
VALUE "InternalName", "freeglutdll\0"
VALUE "LegalCopyright", "Copyright © 1999-2000 Pawel W. Olszta, 2000-2012 Stephen J. Baker\0"
/* VALUE "LegalTrademarks", "\0" */
VALUE "OriginalFilename", "freeglut.dll\0"
/* VALUE "PrivateBuild", "\0" */
VALUE "ProductName", "Freeglut OpenGL Utility Toolkit\0"
VALUE "ProductVersion", "@VERSION_MAJOR@, @VERSION_MINOR@, @VERSION_PATCH@, 0\0"
/* VALUE "SpecialBuild", "\0" */
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1200
END
END

22
include/GL/freeglut.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef __FREEGLUT_H__
#define __FREEGLUT_H__
/*
* freeglut.h
*
* The freeglut library include file
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include "freeglut_std.h"
#include "freeglut_ext.h"
/*** END OF FILE ***/
#endif /* __FREEGLUT_H__ */

295
include/GL/freeglut_ext.h Normal file
View File

@ -0,0 +1,295 @@
#ifndef __FREEGLUT_EXT_H__
#define __FREEGLUT_EXT_H__
/*
* freeglut_ext.h
*
* The non-GLUT-compatible extensions to the freeglut library include file
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 2 1999
*
* 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
* PAWEL W. OLSZTA 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.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Additional GLUT Key definitions for the Special key function
*/
#define GLUT_KEY_NUM_LOCK 0x006D
#define GLUT_KEY_BEGIN 0x006E
#define GLUT_KEY_DELETE 0x006F
#define GLUT_KEY_SHIFT_L 0x0070
#define GLUT_KEY_SHIFT_R 0x0071
#define GLUT_KEY_CTRL_L 0x0072
#define GLUT_KEY_CTRL_R 0x0073
#define GLUT_KEY_ALT_L 0x0074
#define GLUT_KEY_ALT_R 0x0075
#define GLUT_KEY_SUPER_L 0x0076
#define GLUT_KEY_SUPER_R 0x0077
/*
* Additional GLUT modifiers
*/
#define GLUT_ACTIVE_SUPER 0x0008
/*
* GLUT API Extension macro definitions -- behaviour when the user clicks on an "x" to close a window
*/
#define GLUT_ACTION_EXIT 0
#define GLUT_ACTION_GLUTMAINLOOP_RETURNS 1
#define GLUT_ACTION_CONTINUE_EXECUTION 2
/*
* Create a new rendering context when the user opens a new window?
*/
#define GLUT_CREATE_NEW_CONTEXT 0
#define GLUT_USE_CURRENT_CONTEXT 1
/*
* Direct/Indirect rendering context options (has meaning only in Unix/X11)
*/
#define GLUT_FORCE_INDIRECT_CONTEXT 0
#define GLUT_ALLOW_DIRECT_CONTEXT 1
#define GLUT_TRY_DIRECT_CONTEXT 2
#define GLUT_FORCE_DIRECT_CONTEXT 3
/*
* GLUT API Extension macro definitions -- the glutGet parameters
*/
#define GLUT_INIT_STATE 0x007C
#define GLUT_ACTION_ON_WINDOW_CLOSE 0x01F9
#define GLUT_WINDOW_BORDER_WIDTH 0x01FA
#define GLUT_WINDOW_BORDER_HEIGHT 0x01FB
#define GLUT_WINDOW_HEADER_HEIGHT 0x01FB /* Docs say it should always have been GLUT_WINDOW_BORDER_HEIGHT, keep this for backward compatibility */
#define GLUT_VERSION 0x01FC
#define GLUT_RENDERING_CONTEXT 0x01FD
#define GLUT_DIRECT_RENDERING 0x01FE
#define GLUT_FULL_SCREEN 0x01FF
#define GLUT_SKIP_STALE_MOTION_EVENTS 0x0204
#define GLUT_GEOMETRY_VISUALIZE_NORMALS 0x0205
#define GLUT_STROKE_FONT_DRAW_JOIN_DOTS 0x0206 /* Draw dots between line segments of stroke fonts? */
#define GLUT_ALLOW_NEGATIVE_WINDOW_POSITION 0x0207 /* GLUT doesn't allow negative window positions by default */
#define GLUT_WINDOW_SRGB 0x007D
/*
* New tokens for glutInitDisplayMode.
* Only one GLUT_AUXn bit may be used at a time.
* Value 0x0400 is defined in OpenGLUT.
*/
#define GLUT_AUX 0x1000
#define GLUT_AUX1 0x1000
#define GLUT_AUX2 0x2000
#define GLUT_AUX3 0x4000
#define GLUT_AUX4 0x8000
/*
* Context-related flags, see fg_state.c
* Set the requested OpenGL version
*/
#define GLUT_INIT_MAJOR_VERSION 0x0200
#define GLUT_INIT_MINOR_VERSION 0x0201
#define GLUT_INIT_FLAGS 0x0202
#define GLUT_INIT_PROFILE 0x0203
/*
* Flags for glutInitContextFlags, see fg_init.c
*/
#define GLUT_DEBUG 0x0001
#define GLUT_FORWARD_COMPATIBLE 0x0002
/*
* Flags for glutInitContextProfile, see fg_init.c
*/
#define GLUT_CORE_PROFILE 0x0001
#define GLUT_COMPATIBILITY_PROFILE 0x0002
/*
* GLUT API Extension macro definitions -- Spaceball button definitions
*/
#define GLUT_SPACEBALL_BUTTON_A 0x0001
#define GLUT_SPACEBALL_BUTTON_B 0x0002
#define GLUT_SPACEBALL_BUTTON_C 0x0004
#define GLUT_SPACEBALL_BUTTON_D 0x0008
#define GLUT_SPACEBALL_BUTTON_E 0x0010
/*
* Process loop function, see fg_main.c
*/
FGAPI void FGAPIENTRY glutMainLoopEvent( void );
FGAPI void FGAPIENTRY glutLeaveMainLoop( void );
FGAPI void FGAPIENTRY glutExit ( void );
/*
* Window management functions, see fg_window.c
*/
FGAPI void FGAPIENTRY glutFullScreenToggle( void );
FGAPI void FGAPIENTRY glutLeaveFullScreen( void );
/*
* Menu functions
*/
FGAPI void FGAPIENTRY glutSetMenuFont( int menuID, void* font );
/*
* Window-specific callback functions, see fg_callbacks.c
*/
FGAPI void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) );
FGAPI void FGAPIENTRY glutPositionFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutCloseFunc( void (* callback)( void ) );
FGAPI void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) );
/* And also a destruction callback for menus */
FGAPI void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) );
/*
* State setting and retrieval functions, see fg_state.c
*/
FGAPI void FGAPIENTRY glutSetOption ( GLenum option_flag, int value );
FGAPI int * FGAPIENTRY glutGetModeValues(GLenum mode, int * size);
/* A.Donev: User-data manipulation */
FGAPI void* FGAPIENTRY glutGetWindowData( void );
FGAPI void FGAPIENTRY glutSetWindowData(void* data);
FGAPI void* FGAPIENTRY glutGetMenuData( void );
FGAPI void FGAPIENTRY glutSetMenuData(void* data);
/*
* Font stuff, see fg_font.c
*/
FGAPI int FGAPIENTRY glutBitmapHeight( void* font );
FGAPI GLfloat FGAPIENTRY glutStrokeHeight( void* font );
FGAPI void FGAPIENTRY glutBitmapString( void* font, const unsigned char *string );
FGAPI void FGAPIENTRY glutStrokeString( void* font, const unsigned char *string );
/*
* Geometry functions, see fg_geometry.c
*/
FGAPI void FGAPIENTRY glutWireRhombicDodecahedron( void );
FGAPI void FGAPIENTRY glutSolidRhombicDodecahedron( void );
FGAPI void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, double offset[3], double scale );
FGAPI void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, double offset[3], double scale );
FGAPI void FGAPIENTRY glutWireCylinder( double radius, double height, GLint slices, GLint stacks);
FGAPI void FGAPIENTRY glutSolidCylinder( double radius, double height, GLint slices, GLint stacks);
/*
* Rest of functions for rendering Newell's teaset, found in fg_teapot.c
* NB: front facing polygons have clockwise winding, not counter clockwise
*/
FGAPI void FGAPIENTRY glutWireTeacup( double size );
FGAPI void FGAPIENTRY glutSolidTeacup( double size );
FGAPI void FGAPIENTRY glutWireTeaspoon( double size );
FGAPI void FGAPIENTRY glutSolidTeaspoon( double size );
/*
* Extension functions, see fg_ext.c
*/
typedef void (*GLUTproc)();
FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
/*
* Multi-touch/multi-pointer extensions
*/
#define GLUT_HAS_MULTI 1
/* TODO: add device_id parameter,
cf. http://sourceforge.net/mailarchive/forum.php?thread_name=20120518071314.GA28061%40perso.beuc.net&forum_name=freeglut-developer */
FGAPI void FGAPIENTRY glutMultiEntryFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutMultiButtonFunc( void (* callback)( int, int, int, int, int ) );
FGAPI void FGAPIENTRY glutMultiMotionFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutMultiPassiveFunc( void (* callback)( int, int, int ) );
/*
* Joystick functions, see fg_joystick.c
*/
/* USE OF THESE FUNCTIONS IS DEPRECATED !!!!! */
/* If you have a serious need for these functions in your application, please either
* contact the "freeglut" developer community at freeglut-developer@lists.sourceforge.net,
* switch to the OpenGLUT library, or else port your joystick functionality over to PLIB's
* "js" library.
*/
int glutJoystickGetNumAxes( int ident );
int glutJoystickGetNumButtons( int ident );
int glutJoystickNotWorking( int ident );
float glutJoystickGetDeadBand( int ident, int axis );
void glutJoystickSetDeadBand( int ident, int axis, float db );
float glutJoystickGetSaturation( int ident, int axis );
void glutJoystickSetSaturation( int ident, int axis, float st );
void glutJoystickSetMinRange( int ident, float *axes );
void glutJoystickSetMaxRange( int ident, float *axes );
void glutJoystickSetCenter( int ident, float *axes );
void glutJoystickGetMinRange( int ident, float *axes );
void glutJoystickGetMaxRange( int ident, float *axes );
void glutJoystickGetCenter( int ident, float *axes );
/*
* Initialization functions, see fg_init.c
*/
/* to get the typedef for va_list */
#include <stdarg.h>
FGAPI void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion );
FGAPI void FGAPIENTRY glutInitContextFlags( int flags );
FGAPI void FGAPIENTRY glutInitContextProfile( int profile );
FGAPI void FGAPIENTRY glutInitErrorFunc( void (* callback)( const char *fmt, va_list ap ) );
FGAPI void FGAPIENTRY glutInitWarningFunc( void (* callback)( const char *fmt, va_list ap ) );
/* OpenGL >= 2.0 support */
FGAPI void FGAPIENTRY glutSetVertexAttribCoord3( GLint attrib );
FGAPI void FGAPIENTRY glutSetVertexAttribNormal( GLint attrib );
FGAPI void FGAPIENTRY glutSetVertexAttribTexCoord2( GLint attrib );
/* Mobile platforms lifecycle */
FGAPI void FGAPIENTRY glutInitContextFunc( void (* callback)( void ) );
FGAPI void FGAPIENTRY glutAppStatusFunc( void (* callback)( int ) );
/* state flags that can be passed to callback set by glutAppStatusFunc */
#define GLUT_APPSTATUS_PAUSE 0x0001
#define GLUT_APPSTATUS_RESUME 0x0002
/*
* GLUT API macro definitions -- the display mode definitions
*/
#define GLUT_CAPTIONLESS 0x0400
#define GLUT_BORDERLESS 0x0800
#define GLUT_SRGB 0x1000
/* User-argument callbacks and implementation */
#include "freeglut_ucall.h"
#ifdef __cplusplus
}
#endif
/*** END OF FILE ***/
#endif /* __FREEGLUT_EXT_H__ */

653
include/GL/freeglut_std.h Normal file
View File

@ -0,0 +1,653 @@
#ifndef __FREEGLUT_STD_H__
#define __FREEGLUT_STD_H__
/*
* freeglut_std.h
*
* The GLUT-compatible part of the freeglut library include file
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: Thu Dec 2 1999
*
* 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
* PAWEL W. OLSZTA 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.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Under windows, we have to differentiate between static and dynamic libraries
*/
#ifdef _WIN32
/* #pragma may not be supported by some compilers.
* Discussion by FreeGLUT developers suggests that
* Visual C++ specific code involving pragmas may
* need to move to a separate header. 24th Dec 2003
*/
/* Define FREEGLUT_LIB_PRAGMAS to 1 to include library
* pragmas or to 0 to exclude library pragmas.
* The default behavior depends on the compiler/platform.
*/
# ifndef FREEGLUT_LIB_PRAGMAS
# if ( defined(_MSC_VER) || defined(__WATCOMC__) ) && !defined(_WIN32_WCE)
# define FREEGLUT_LIB_PRAGMAS 1
# else
# define FREEGLUT_LIB_PRAGMAS 0
# endif
# endif
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN 1
# endif
# ifndef NOMINMAX
# define NOMINMAX
# endif
# include <windows.h>
/* Windows static library */
# ifdef FREEGLUT_STATIC
# define FGAPI
# define FGAPIENTRY
/* Link with Win32 static freeglut lib */
# if FREEGLUT_LIB_PRAGMAS
# ifdef NDEBUG
# pragma comment (lib, "freeglut_static.lib")
# else
# pragma comment (lib, "freeglut_staticd.lib")
# endif
# endif
/* Windows shared library (DLL) */
# else
# define FGAPIENTRY __stdcall
# if defined(FREEGLUT_EXPORTS)
# define FGAPI __declspec(dllexport)
# else
# define FGAPI __declspec(dllimport)
/* Link with Win32 shared freeglut lib */
# if FREEGLUT_LIB_PRAGMAS
# ifdef NDEBUG
# pragma comment (lib, "freeglut.lib")
# else
# pragma comment (lib, "freeglutd.lib")
# endif
# endif
# endif
# endif
/* Drag in other Windows libraries as required by FreeGLUT */
# if FREEGLUT_LIB_PRAGMAS
# pragma comment (lib, "glu32.lib") /* link OpenGL Utility lib */
# pragma comment (lib, "opengl32.lib") /* link Microsoft OpenGL lib */
# pragma comment (lib, "gdi32.lib") /* link Windows GDI lib */
# pragma comment (lib, "winmm.lib") /* link Windows MultiMedia lib */
# pragma comment (lib, "user32.lib") /* link Windows user lib */
# endif
#else
/* Non-Windows definition of FGAPI and FGAPIENTRY */
# define FGAPI
# define FGAPIENTRY
#endif
/*
* The freeglut and GLUT API versions
*/
#define FREEGLUT 1
#define GLUT_API_VERSION 4
#define GLUT_XLIB_IMPLEMENTATION 13
/* Deprecated:
cf. http://sourceforge.net/mailarchive/forum.php?thread_name=CABcAi1hw7cr4xtigckaGXB5X8wddLfMcbA_rZ3NAuwMrX_zmsw%40mail.gmail.com&forum_name=freeglut-developer */
#define FREEGLUT_VERSION_2_0 1
/*
* Always include OpenGL and GLU headers
*/
/* Note: FREEGLUT_GLES is only used to cleanly bootstrap headers
inclusion here; use GLES constants directly
(e.g. GL_ES_VERSION_2_0) for all other needs */
#ifdef FREEGLUT_GLES
# include <EGL/egl.h>
# include <GLES/gl.h>
# include <GLES2/gl2.h>
#elif __APPLE__
# include <OpenGL/gl.h>
# include <OpenGL/glu.h>
#else
# include <GL/gl.h>
# include <GL/glu.h>
#endif
/*
* GLUT API macro definitions -- the special key codes:
*/
#define GLUT_KEY_F1 0x0001
#define GLUT_KEY_F2 0x0002
#define GLUT_KEY_F3 0x0003
#define GLUT_KEY_F4 0x0004
#define GLUT_KEY_F5 0x0005
#define GLUT_KEY_F6 0x0006
#define GLUT_KEY_F7 0x0007
#define GLUT_KEY_F8 0x0008
#define GLUT_KEY_F9 0x0009
#define GLUT_KEY_F10 0x000A
#define GLUT_KEY_F11 0x000B
#define GLUT_KEY_F12 0x000C
#define GLUT_KEY_LEFT 0x0064
#define GLUT_KEY_UP 0x0065
#define GLUT_KEY_RIGHT 0x0066
#define GLUT_KEY_DOWN 0x0067
#define GLUT_KEY_PAGE_UP 0x0068
#define GLUT_KEY_PAGE_DOWN 0x0069
#define GLUT_KEY_HOME 0x006A
#define GLUT_KEY_END 0x006B
#define GLUT_KEY_INSERT 0x006C
/*
* GLUT API macro definitions -- mouse state definitions
*/
#define GLUT_LEFT_BUTTON 0x0000
#define GLUT_MIDDLE_BUTTON 0x0001
#define GLUT_RIGHT_BUTTON 0x0002
#define GLUT_DOWN 0x0000
#define GLUT_UP 0x0001
#define GLUT_LEFT 0x0000
#define GLUT_ENTERED 0x0001
/*
* GLUT API macro definitions -- the display mode definitions
*/
#define GLUT_RGB 0x0000
#define GLUT_RGBA 0x0000
#define GLUT_INDEX 0x0001
#define GLUT_SINGLE 0x0000
#define GLUT_DOUBLE 0x0002
#define GLUT_ACCUM 0x0004
#define GLUT_ALPHA 0x0008
#define GLUT_DEPTH 0x0010
#define GLUT_STENCIL 0x0020
#define GLUT_MULTISAMPLE 0x0080
#define GLUT_STEREO 0x0100
#define GLUT_LUMINANCE 0x0200
/*
* GLUT API macro definitions -- windows and menu related definitions
*/
#define GLUT_MENU_NOT_IN_USE 0x0000
#define GLUT_MENU_IN_USE 0x0001
#define GLUT_NOT_VISIBLE 0x0000
#define GLUT_VISIBLE 0x0001
#define GLUT_HIDDEN 0x0000
#define GLUT_FULLY_RETAINED 0x0001
#define GLUT_PARTIALLY_RETAINED 0x0002
#define GLUT_FULLY_COVERED 0x0003
/*
* GLUT API macro definitions -- fonts definitions
*
* Steve Baker suggested to make it binary compatible with GLUT:
*/
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__WATCOMC__)
# define GLUT_STROKE_ROMAN ((void *)0x0000)
# define GLUT_STROKE_MONO_ROMAN ((void *)0x0001)
# define GLUT_BITMAP_9_BY_15 ((void *)0x0002)
# define GLUT_BITMAP_8_BY_13 ((void *)0x0003)
# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *)0x0004)
# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *)0x0005)
# define GLUT_BITMAP_HELVETICA_10 ((void *)0x0006)
# define GLUT_BITMAP_HELVETICA_12 ((void *)0x0007)
# define GLUT_BITMAP_HELVETICA_18 ((void *)0x0008)
#else
/*
* I don't really know if it's a good idea... But here it goes:
*/
extern void* glutStrokeRoman;
extern void* glutStrokeMonoRoman;
extern void* glutBitmap9By15;
extern void* glutBitmap8By13;
extern void* glutBitmapTimesRoman10;
extern void* glutBitmapTimesRoman24;
extern void* glutBitmapHelvetica10;
extern void* glutBitmapHelvetica12;
extern void* glutBitmapHelvetica18;
/*
* Those pointers will be used by following definitions:
*/
# define GLUT_STROKE_ROMAN ((void *) &glutStrokeRoman)
# define GLUT_STROKE_MONO_ROMAN ((void *) &glutStrokeMonoRoman)
# define GLUT_BITMAP_9_BY_15 ((void *) &glutBitmap9By15)
# define GLUT_BITMAP_8_BY_13 ((void *) &glutBitmap8By13)
# define GLUT_BITMAP_TIMES_ROMAN_10 ((void *) &glutBitmapTimesRoman10)
# define GLUT_BITMAP_TIMES_ROMAN_24 ((void *) &glutBitmapTimesRoman24)
# define GLUT_BITMAP_HELVETICA_10 ((void *) &glutBitmapHelvetica10)
# define GLUT_BITMAP_HELVETICA_12 ((void *) &glutBitmapHelvetica12)
# define GLUT_BITMAP_HELVETICA_18 ((void *) &glutBitmapHelvetica18)
#endif
/*
* GLUT API macro definitions -- the glutGet parameters
*/
#define GLUT_WINDOW_X 0x0064
#define GLUT_WINDOW_Y 0x0065
#define GLUT_WINDOW_WIDTH 0x0066
#define GLUT_WINDOW_HEIGHT 0x0067
#define GLUT_WINDOW_BUFFER_SIZE 0x0068
#define GLUT_WINDOW_STENCIL_SIZE 0x0069
#define GLUT_WINDOW_DEPTH_SIZE 0x006A
#define GLUT_WINDOW_RED_SIZE 0x006B
#define GLUT_WINDOW_GREEN_SIZE 0x006C
#define GLUT_WINDOW_BLUE_SIZE 0x006D
#define GLUT_WINDOW_ALPHA_SIZE 0x006E
#define GLUT_WINDOW_ACCUM_RED_SIZE 0x006F
#define GLUT_WINDOW_ACCUM_GREEN_SIZE 0x0070
#define GLUT_WINDOW_ACCUM_BLUE_SIZE 0x0071
#define GLUT_WINDOW_ACCUM_ALPHA_SIZE 0x0072
#define GLUT_WINDOW_DOUBLEBUFFER 0x0073
#define GLUT_WINDOW_RGBA 0x0074
#define GLUT_WINDOW_PARENT 0x0075
#define GLUT_WINDOW_NUM_CHILDREN 0x0076
#define GLUT_WINDOW_COLORMAP_SIZE 0x0077
#define GLUT_WINDOW_NUM_SAMPLES 0x0078
#define GLUT_WINDOW_STEREO 0x0079
#define GLUT_WINDOW_CURSOR 0x007A
#define GLUT_SCREEN_WIDTH 0x00C8
#define GLUT_SCREEN_HEIGHT 0x00C9
#define GLUT_SCREEN_WIDTH_MM 0x00CA
#define GLUT_SCREEN_HEIGHT_MM 0x00CB
#define GLUT_MENU_NUM_ITEMS 0x012C
#define GLUT_DISPLAY_MODE_POSSIBLE 0x0190
#define GLUT_INIT_WINDOW_X 0x01F4
#define GLUT_INIT_WINDOW_Y 0x01F5
#define GLUT_INIT_WINDOW_WIDTH 0x01F6
#define GLUT_INIT_WINDOW_HEIGHT 0x01F7
#define GLUT_INIT_DISPLAY_MODE 0x01F8
#define GLUT_ELAPSED_TIME 0x02BC
#define GLUT_WINDOW_FORMAT_ID 0x007B
/*
* GLUT API macro definitions -- the glutDeviceGet parameters
*/
#define GLUT_HAS_KEYBOARD 0x0258
#define GLUT_HAS_MOUSE 0x0259
#define GLUT_HAS_SPACEBALL 0x025A
#define GLUT_HAS_DIAL_AND_BUTTON_BOX 0x025B
#define GLUT_HAS_TABLET 0x025C
#define GLUT_NUM_MOUSE_BUTTONS 0x025D
#define GLUT_NUM_SPACEBALL_BUTTONS 0x025E
#define GLUT_NUM_BUTTON_BOX_BUTTONS 0x025F
#define GLUT_NUM_DIALS 0x0260
#define GLUT_NUM_TABLET_BUTTONS 0x0261
#define GLUT_DEVICE_IGNORE_KEY_REPEAT 0x0262
#define GLUT_DEVICE_KEY_REPEAT 0x0263
#define GLUT_HAS_JOYSTICK 0x0264
#define GLUT_OWNS_JOYSTICK 0x0265
#define GLUT_JOYSTICK_BUTTONS 0x0266
#define GLUT_JOYSTICK_AXES 0x0267
#define GLUT_JOYSTICK_POLL_RATE 0x0268
/*
* GLUT API macro definitions -- the glutLayerGet parameters
*/
#define GLUT_OVERLAY_POSSIBLE 0x0320
#define GLUT_LAYER_IN_USE 0x0321
#define GLUT_HAS_OVERLAY 0x0322
#define GLUT_TRANSPARENT_INDEX 0x0323
#define GLUT_NORMAL_DAMAGED 0x0324
#define GLUT_OVERLAY_DAMAGED 0x0325
/*
* GLUT API macro definitions -- the glutVideoResizeGet parameters
*/
#define GLUT_VIDEO_RESIZE_POSSIBLE 0x0384
#define GLUT_VIDEO_RESIZE_IN_USE 0x0385
#define GLUT_VIDEO_RESIZE_X_DELTA 0x0386
#define GLUT_VIDEO_RESIZE_Y_DELTA 0x0387
#define GLUT_VIDEO_RESIZE_WIDTH_DELTA 0x0388
#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA 0x0389
#define GLUT_VIDEO_RESIZE_X 0x038A
#define GLUT_VIDEO_RESIZE_Y 0x038B
#define GLUT_VIDEO_RESIZE_WIDTH 0x038C
#define GLUT_VIDEO_RESIZE_HEIGHT 0x038D
/*
* GLUT API macro definitions -- the glutUseLayer parameters
*/
#define GLUT_NORMAL 0x0000
#define GLUT_OVERLAY 0x0001
/*
* GLUT API macro definitions -- the glutGetModifiers parameters
*/
#define GLUT_ACTIVE_SHIFT 0x0001
#define GLUT_ACTIVE_CTRL 0x0002
#define GLUT_ACTIVE_ALT 0x0004
/*
* GLUT API macro definitions -- the glutSetCursor parameters
*/
#define GLUT_CURSOR_RIGHT_ARROW 0x0000
#define GLUT_CURSOR_LEFT_ARROW 0x0001
#define GLUT_CURSOR_INFO 0x0002
#define GLUT_CURSOR_DESTROY 0x0003
#define GLUT_CURSOR_HELP 0x0004
#define GLUT_CURSOR_CYCLE 0x0005
#define GLUT_CURSOR_SPRAY 0x0006
#define GLUT_CURSOR_WAIT 0x0007
#define GLUT_CURSOR_TEXT 0x0008
#define GLUT_CURSOR_CROSSHAIR 0x0009
#define GLUT_CURSOR_UP_DOWN 0x000A
#define GLUT_CURSOR_LEFT_RIGHT 0x000B
#define GLUT_CURSOR_TOP_SIDE 0x000C
#define GLUT_CURSOR_BOTTOM_SIDE 0x000D
#define GLUT_CURSOR_LEFT_SIDE 0x000E
#define GLUT_CURSOR_RIGHT_SIDE 0x000F
#define GLUT_CURSOR_TOP_LEFT_CORNER 0x0010
#define GLUT_CURSOR_TOP_RIGHT_CORNER 0x0011
#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 0x0012
#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 0x0013
#define GLUT_CURSOR_INHERIT 0x0064
#define GLUT_CURSOR_NONE 0x0065
#define GLUT_CURSOR_FULL_CROSSHAIR 0x0066
/*
* GLUT API macro definitions -- RGB color component specification definitions
*/
#define GLUT_RED 0x0000
#define GLUT_GREEN 0x0001
#define GLUT_BLUE 0x0002
/*
* GLUT API macro definitions -- additional keyboard and joystick definitions
*/
#define GLUT_KEY_REPEAT_OFF 0x0000
#define GLUT_KEY_REPEAT_ON 0x0001
#define GLUT_KEY_REPEAT_DEFAULT 0x0002
#define GLUT_JOYSTICK_BUTTON_A 0x0001
#define GLUT_JOYSTICK_BUTTON_B 0x0002
#define GLUT_JOYSTICK_BUTTON_C 0x0004
#define GLUT_JOYSTICK_BUTTON_D 0x0008
/*
* GLUT API macro definitions -- game mode definitions
*/
#define GLUT_GAME_MODE_ACTIVE 0x0000
#define GLUT_GAME_MODE_POSSIBLE 0x0001
#define GLUT_GAME_MODE_WIDTH 0x0002
#define GLUT_GAME_MODE_HEIGHT 0x0003
#define GLUT_GAME_MODE_PIXEL_DEPTH 0x0004
#define GLUT_GAME_MODE_REFRESH_RATE 0x0005
#define GLUT_GAME_MODE_DISPLAY_CHANGED 0x0006
/*
* Initialization functions, see fglut_init.c
*/
FGAPI void FGAPIENTRY glutInit( int* pargc, char** argv );
FGAPI void FGAPIENTRY glutInitWindowPosition( int x, int y );
FGAPI void FGAPIENTRY glutInitWindowSize( int width, int height );
FGAPI void FGAPIENTRY glutInitDisplayMode( unsigned int displayMode );
FGAPI void FGAPIENTRY glutInitDisplayString( const char* displayMode );
/*
* Process loop function, see fg_main.c
*/
FGAPI void FGAPIENTRY glutMainLoop( void );
/*
* Window management functions, see fg_window.c
*/
FGAPI int FGAPIENTRY glutCreateWindow( const char* title );
FGAPI int FGAPIENTRY glutCreateSubWindow( int window, int x, int y, int width, int height );
FGAPI void FGAPIENTRY glutDestroyWindow( int window );
FGAPI void FGAPIENTRY glutSetWindow( int window );
FGAPI int FGAPIENTRY glutGetWindow( void );
FGAPI void FGAPIENTRY glutSetWindowTitle( const char* title );
FGAPI void FGAPIENTRY glutSetIconTitle( const char* title );
FGAPI void FGAPIENTRY glutReshapeWindow( int width, int height );
FGAPI void FGAPIENTRY glutPositionWindow( int x, int y );
FGAPI void FGAPIENTRY glutShowWindow( void );
FGAPI void FGAPIENTRY glutHideWindow( void );
FGAPI void FGAPIENTRY glutIconifyWindow( void );
FGAPI void FGAPIENTRY glutPushWindow( void );
FGAPI void FGAPIENTRY glutPopWindow( void );
FGAPI void FGAPIENTRY glutFullScreen( void );
/*
* Display-related functions, see fg_display.c
*/
FGAPI void FGAPIENTRY glutPostWindowRedisplay( int window );
FGAPI void FGAPIENTRY glutPostRedisplay( void );
FGAPI void FGAPIENTRY glutSwapBuffers( void );
/*
* Mouse cursor functions, see fg_cursor.c
*/
FGAPI void FGAPIENTRY glutWarpPointer( int x, int y );
FGAPI void FGAPIENTRY glutSetCursor( int cursor );
/*
* Overlay stuff, see fg_overlay.c
*/
FGAPI void FGAPIENTRY glutEstablishOverlay( void );
FGAPI void FGAPIENTRY glutRemoveOverlay( void );
FGAPI void FGAPIENTRY glutUseLayer( GLenum layer );
FGAPI void FGAPIENTRY glutPostOverlayRedisplay( void );
FGAPI void FGAPIENTRY glutPostWindowOverlayRedisplay( int window );
FGAPI void FGAPIENTRY glutShowOverlay( void );
FGAPI void FGAPIENTRY glutHideOverlay( void );
/*
* Menu stuff, see fg_menu.c
*/
FGAPI int FGAPIENTRY glutCreateMenu( void (* callback)( int menu ) );
FGAPI void FGAPIENTRY glutDestroyMenu( int menu );
FGAPI int FGAPIENTRY glutGetMenu( void );
FGAPI void FGAPIENTRY glutSetMenu( int menu );
FGAPI void FGAPIENTRY glutAddMenuEntry( const char* label, int value );
FGAPI void FGAPIENTRY glutAddSubMenu( const char* label, int subMenu );
FGAPI void FGAPIENTRY glutChangeToMenuEntry( int item, const char* label, int value );
FGAPI void FGAPIENTRY glutChangeToSubMenu( int item, const char* label, int value );
FGAPI void FGAPIENTRY glutRemoveMenuItem( int item );
FGAPI void FGAPIENTRY glutAttachMenu( int button );
FGAPI void FGAPIENTRY glutDetachMenu( int button );
/*
* Global callback functions, see fg_callbacks.c
*/
FGAPI void FGAPIENTRY glutTimerFunc( unsigned int time, void (* callback)( int ), int value );
FGAPI void FGAPIENTRY glutIdleFunc( void (* callback)( void ) );
/*
* Window-specific callback functions, see fg_callbacks.c
*/
FGAPI void FGAPIENTRY glutKeyboardFunc( void (* callback)( unsigned char, int, int ) );
FGAPI void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) );
FGAPI void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) );
FGAPI void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutEntryFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutKeyboardUpFunc( void (* callback)( unsigned char, int, int ) );
FGAPI void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutJoystickFunc( void (* callback)( unsigned int, int, int, int ), int pollInterval );
FGAPI void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) );
FGAPI void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) );
FGAPI void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) );
FGAPI void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) );
FGAPI void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) );
/*
* State setting and retrieval functions, see fg_state.c
*/
FGAPI int FGAPIENTRY glutGet( GLenum query );
FGAPI int FGAPIENTRY glutDeviceGet( GLenum query );
FGAPI int FGAPIENTRY glutGetModifiers( void );
FGAPI int FGAPIENTRY glutLayerGet( GLenum query );
/*
* Font stuff, see fg_font.c
*/
FGAPI void FGAPIENTRY glutBitmapCharacter( void* font, int character );
FGAPI int FGAPIENTRY glutBitmapWidth( void* font, int character );
FGAPI void FGAPIENTRY glutStrokeCharacter( void* font, int character );
FGAPI int FGAPIENTRY glutStrokeWidth( void* font, int character );
FGAPI GLfloat FGAPIENTRY glutStrokeWidthf( void* font, int character ); /* GLUT 3.8 */
FGAPI int FGAPIENTRY glutBitmapLength( void* font, const unsigned char* string );
FGAPI int FGAPIENTRY glutStrokeLength( void* font, const unsigned char* string );
FGAPI GLfloat FGAPIENTRY glutStrokeLengthf( void* font, const unsigned char *string ); /* GLUT 3.8 */
/*
* Geometry functions, see fg_geometry.c
*/
FGAPI void FGAPIENTRY glutWireCube( double size );
FGAPI void FGAPIENTRY glutSolidCube( double size );
FGAPI void FGAPIENTRY glutWireSphere( double radius, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutSolidSphere( double radius, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutWireCone( double base, double height, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutSolidCone( double base, double height, GLint slices, GLint stacks );
FGAPI void FGAPIENTRY glutWireTorus( double innerRadius, double outerRadius, GLint sides, GLint rings );
FGAPI void FGAPIENTRY glutSolidTorus( double innerRadius, double outerRadius, GLint sides, GLint rings );
FGAPI void FGAPIENTRY glutWireDodecahedron( void );
FGAPI void FGAPIENTRY glutSolidDodecahedron( void );
FGAPI void FGAPIENTRY glutWireOctahedron( void );
FGAPI void FGAPIENTRY glutSolidOctahedron( void );
FGAPI void FGAPIENTRY glutWireTetrahedron( void );
FGAPI void FGAPIENTRY glutSolidTetrahedron( void );
FGAPI void FGAPIENTRY glutWireIcosahedron( void );
FGAPI void FGAPIENTRY glutSolidIcosahedron( void );
/*
* Teapot rendering functions, found in fg_teapot.c
* NB: front facing polygons have clockwise winding, not counter clockwise
*/
FGAPI void FGAPIENTRY glutWireTeapot( double size );
FGAPI void FGAPIENTRY glutSolidTeapot( double size );
/*
* Game mode functions, see fg_gamemode.c
*/
FGAPI void FGAPIENTRY glutGameModeString( const char* string );
FGAPI int FGAPIENTRY glutEnterGameMode( void );
FGAPI void FGAPIENTRY glutLeaveGameMode( void );
FGAPI int FGAPIENTRY glutGameModeGet( GLenum query );
/*
* Video resize functions, see fg_videoresize.c
*/
FGAPI int FGAPIENTRY glutVideoResizeGet( GLenum query );
FGAPI void FGAPIENTRY glutSetupVideoResizing( void );
FGAPI void FGAPIENTRY glutStopVideoResizing( void );
FGAPI void FGAPIENTRY glutVideoResize( int x, int y, int width, int height );
FGAPI void FGAPIENTRY glutVideoPan( int x, int y, int width, int height );
/*
* Colormap functions, see fg_misc.c
*/
FGAPI void FGAPIENTRY glutSetColor( int color, GLfloat red, GLfloat green, GLfloat blue );
FGAPI GLfloat FGAPIENTRY glutGetColor( int color, int component );
FGAPI void FGAPIENTRY glutCopyColormap( int window );
/*
* Misc keyboard and joystick functions, see fg_misc.c
*/
FGAPI void FGAPIENTRY glutIgnoreKeyRepeat( int ignore );
FGAPI void FGAPIENTRY glutSetKeyRepeat( int repeatMode );
FGAPI void FGAPIENTRY glutForceJoystickFunc( void );
/*
* Misc functions, see fg_misc.c
*/
FGAPI int FGAPIENTRY glutExtensionSupported( const char* extension );
FGAPI void FGAPIENTRY glutReportErrors( void );
/* Comment from glut.h of classic GLUT:
Win32 has an annoying issue where there are multiple C run-time
libraries (CRTs). If the executable is linked with a different CRT
from the GLUT DLL, the GLUT DLL will not share the same CRT static
data seen by the executable. In particular, atexit callbacks registered
in the executable will not be called if GLUT calls its (different)
exit routine). GLUT is typically built with the
"/MD" option (the CRT with multithreading DLL support), but the Visual
C++ linker default is "/ML" (the single threaded CRT).
One workaround to this issue is requiring users to always link with
the same CRT as GLUT is compiled with. That requires users supply a
non-standard option. GLUT 3.7 has its own built-in workaround where
the executable's "exit" function pointer is covertly passed to GLUT.
GLUT then calls the executable's exit function pointer to ensure that
any "atexit" calls registered by the application are called if GLUT
needs to exit.
Note that the __glut*WithExit routines should NEVER be called directly.
To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */
/* to get the prototype for exit() */
#include <stdlib.h>
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__)
FGAPI void FGAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
FGAPI int FGAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
FGAPI int FGAPIENTRY __glutCreateMenuWithExit(void (* func)(int), void (__cdecl *exitfunc)(int));
#ifndef FREEGLUT_BUILDING_LIB
#if defined(__GNUC__)
#define FGUNUSED __attribute__((unused))
#else
#define FGUNUSED
#endif
static void FGAPIENTRY FGUNUSED glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
#define glutInit glutInit_ATEXIT_HACK
static int FGAPIENTRY FGUNUSED glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
static int FGAPIENTRY FGUNUSED glutCreateMenu_ATEXIT_HACK(void (* func)(int)) { return __glutCreateMenuWithExit(func, exit); }
#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
#endif
#endif
#ifdef __cplusplus
}
#endif
/*** END OF FILE ***/
#endif /* __FREEGLUT_STD_H__ */

113
include/GL/freeglut_ucall.h Normal file
View File

@ -0,0 +1,113 @@
#ifndef __FREEGLUT_UCALL_H__
#define __FREEGLUT_UCALL_H__
/*
* freeglut_ucall.h
*
* Callbacks with user data arguments.
*
* 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
* PAWEL W. OLSZTA 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.
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Menu stuff, see fg_menu.c
*/
FGAPI int FGAPIENTRY glutCreateMenuUcall( void (* callback)( int menu, void* user_data ), void* user_data );
/*
* Global callback functions, see fg_callbacks.c
*/
FGAPI void FGAPIENTRY glutTimerFuncUcall( unsigned int time, void (* callback)( int, void* ), int value, void* user_data );
FGAPI void FGAPIENTRY glutIdleFuncUcall( void (* callback)( void* ), void* user_data );
/*
* Window-specific callback functions, see fg_callbacks.c
*/
FGAPI void FGAPIENTRY glutKeyboardFuncUcall( void (* callback)( unsigned char, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutSpecialFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutReshapeFuncUcall( void (* callback)( int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutVisibilityFuncUcall( void (* callback)( int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutDisplayFuncUcall( void (* callback)( void* ), void* user_data );
FGAPI void FGAPIENTRY glutMouseFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutPassiveMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutEntryFuncUcall( void (* callback)( int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutKeyboardUpFuncUcall( void (* callback)( unsigned char, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutSpecialUpFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutJoystickFuncUcall( void (* callback)( unsigned int, int, int, int, void* ), int pollInterval, void* user_data );
FGAPI void FGAPIENTRY glutMenuStatusFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutOverlayDisplayFuncUcall( void (* callback)( void* ), void* user_data );
FGAPI void FGAPIENTRY glutWindowStatusFuncUcall( void (* callback)( int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutSpaceballMotionFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutSpaceballRotateFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutSpaceballButtonFuncUcall( void (* callback)( int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutButtonBoxFuncUcall( void (* callback)( int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutDialsFuncUcall( void (* callback)( int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutTabletMotionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutTabletButtonFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutMouseWheelFuncUcall( void (* callback)( int, int, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutPositionFuncUcall( void (* callback)( int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutCloseFuncUcall( void (* callback)( void* ), void* user_data );
FGAPI void FGAPIENTRY glutWMCloseFuncUcall( void (* callback)( void* ), void* user_data );
FGAPI void FGAPIENTRY glutMenuDestroyFuncUcall( void (* callback)( void* ), void* user_data );
/*
* Multi-touch/multi-pointer extensions
*/
FGAPI void FGAPIENTRY glutMultiEntryFuncUcall( void (* callback)( int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutMultiButtonFuncUcall( void (* callback)( int, int, int, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutMultiMotionFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
FGAPI void FGAPIENTRY glutMultiPassiveFuncUcall( void (* callback)( int, int, int, void* ), void* user_data );
/*
* Initialization functions, see fg_init.c
*/
#include <stdarg.h>
FGAPI void FGAPIENTRY glutInitErrorFuncUcall( void (* callback)( const char *fmt, va_list ap, void* user_data ), void* user_data );
FGAPI void FGAPIENTRY glutInitWarningFuncUcall( void (* callback)( const char *fmt, va_list ap, void* user_data ), void* user_data );
/* Mobile platforms lifecycle */
FGAPI void FGAPIENTRY glutInitContextFuncUcall( void (* callback)( void* ), void* user_data );
FGAPI void FGAPIENTRY glutAppStatusFuncUcall( void (* callback)( int, void* ), void* user_data );
/*
* Continued "hack" from GLUT applied to Ucall functions.
* For more info, see bottom of freeglut_std.h
*/
/* to get the prototype for exit() */
#include <stdlib.h>
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK) && !defined(__WATCOMC__)
FGAPI int FGAPIENTRY __glutCreateMenuUcallWithExit(void(*func)(int, void*), void(__cdecl *exitfunc)(int), void* user_data);
#ifndef FREEGLUT_BUILDING_LIB
#if defined(__GNUC__)
#define FGUNUSED __attribute__((unused))
#else
#define FGUNUSED
#endif
static int FGAPIENTRY FGUNUSED glutCreateMenuUcall_ATEXIT_HACK(void(*func)(int, void*), void* user_data) { return __glutCreateMenuUcallWithExit(func, exit, user_data); }
#define glutCreateMenuUcall glutCreateMenuUcall_ATEXIT_HACK
#endif
#endif
#ifdef __cplusplus
}
#endif
/*** END OF FILE ***/
#endif /* __FREEGLUT_UCALL_H__ */

21
include/GL/glut.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef __GLUT_H__
#define __GLUT_H__
/*
* glut.h
*
* The freeglut library include file
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include "freeglut_std.h"
/*** END OF FILE ***/
#endif /* __GLUT_H__ */

View File

@ -0,0 +1,7 @@
# CMake toolchain file, cf. README.mingw_cross
SET(CMAKE_SYSTEM_NAME Windows)
IF("${GNU_HOST}" STREQUAL "")
SET(GNU_HOST x86_64-w64-mingw32)
ENDIF()
SET(CMAKE_C_COMPILER ${GNU_HOST}-gcc)
SET(CMAKE_RC_COMPILER ${GNU_HOST}-windres)

309
progs/demos/3dview/3dview.c Normal file
View File

@ -0,0 +1,309 @@
/* 3D view manipulation demo
* Written by John Tsiombikas <nuclear@member.fsf.org>
*
* Demonstrates how to use freeglut callbacks to manipulate a 3D view, similarly
* to how a modelling program or a model viewer would operate.
*
* Rotate: drag with the left mouse button.
* Scale: drag up/down with the right mouse button.
* Pan: drag with the middle mouse button.
*
* Press space to animate the scene and update the display continuously, press
* again to return to updating only when the view needs to change.
* Press escape or q to exit.
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <GL/freeglut.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifdef _MSC_VER
#pragma warning (disable: 4305 4244)
#endif
static const char *helpprompt[] = {"Press F1 for help", 0};
static const char *helptext[] = {
"Rotate: left mouse drag",
" Scale: right mouse drag up/down",
" Pan: middle mouse drag",
"",
"Toggle fullscreen: f",
"Toggle animation: space",
"Quit: escape",
0
};
void idle(void);
void display(void);
void print_help(void);
void reshape(int x, int y);
void keypress(unsigned char key, int x, int y);
void skeypress(int key, int x, int y);
void mouse(int bn, int st, int x, int y);
void motion(int x, int y);
int win_width, win_height;
float cam_theta, cam_phi = 25, cam_dist = 8;
float cam_pan[3];
int mouse_x, mouse_y;
int bnstate[8];
int anim, help;
long anim_start;
long nframes;
#ifndef GL_FRAMEBUFFER_SRGB
#define GL_FRAMEBUFFER_SRGB 0x8db9
#endif
#ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE 0x809d
#endif
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(800, 600);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow("freeglut 3D view demo");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keypress);
glutSpecialFunc(skeypress);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glutMainLoop();
return 0;
}
void idle(void)
{
glutPostRedisplay();
}
void display(void)
{
long tm;
float lpos[] = {-1, 2, 3, 0};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -cam_dist);
glRotatef(cam_phi, 1, 0, 0);
glRotatef(cam_theta, 0, 1, 0);
glTranslatef(cam_pan[0], cam_pan[1], cam_pan[2]);
glLightfv(GL_LIGHT0, GL_POSITION, lpos);
glPushMatrix();
if(anim) {
tm = glutGet(GLUT_ELAPSED_TIME) - anim_start;
glRotatef(tm / 10.0f, 1, 0, 0);
glRotatef(tm / 10.0f, 0, 1, 0);
}
glutSolidTorus(0.3, 1, 16, 24);
glPopMatrix();
glutSolidSphere(0.4, 16, 8);
glPushMatrix();
glTranslatef(-2.5, 0, 0);
glutSolidCube(1.5);
glPopMatrix();
glPushMatrix();
glTranslatef(2.5, -1, 0);
glRotatef(-90, 1, 0, 0);
glutSolidCone(1.1, 2, 16, 2);
glPopMatrix();
glPushMatrix();
glTranslatef(0, -0.5, 2.5);
glFrontFace(GL_CW);
glutSolidTeapot(1.0);
glFrontFace(GL_CCW);
glPopMatrix();
glBegin(GL_QUADS);
glNormal3f(0, 1, 0);
glVertex3f(-5, -1.3, 5);
glVertex3f(5, -1.3, 5);
glVertex3f(5, -1.3, -5);
glVertex3f(-5, -1.3, -5);
glEnd();
print_help();
glutSwapBuffers();
nframes++;
}
void print_help(void)
{
int i;
const char *s, **text;
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, win_width, 0, win_height, -1, 1);
text = help ? helptext : helpprompt;
for(i=0; text[i]; i++) {
glColor3f(0, 0.1, 0);
glRasterPos2f(7, win_height - (i + 1) * 20 - 2);
s = text[i];
while(*s) {
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, *s++);
}
glColor3f(0, 0.9, 0);
glRasterPos2f(5, win_height - (i + 1) * 20);
s = text[i];
while(*s) {
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, *s++);
}
}
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopAttrib();
}
#define ZNEAR 0.5f
void reshape(int x, int y)
{
float vsz, aspect = (float)x / (float)y;
win_width = x;
win_height = y;
glViewport(0, 0, x, y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
vsz = 0.4663f * ZNEAR;
glFrustum(-aspect * vsz, aspect * vsz, -vsz, vsz, 0.5, 500.0);
}
void keypress(unsigned char key, int x, int y)
{
static int fullscr;
static int prev_xsz, prev_ysz;
switch(key) {
case 27:
case 'q':
exit(0);
break;
case ' ':
anim ^= 1;
glutIdleFunc(anim ? idle : 0);
glutPostRedisplay();
if(anim) {
anim_start = glutGet(GLUT_ELAPSED_TIME);
nframes = 0;
} else {
long tm = glutGet(GLUT_ELAPSED_TIME) - anim_start;
long fps = (nframes * 100000) / tm;
printf("framerate: %ld.%ld fps\n", fps / 100, fps % 100);
}
break;
case '\n':
case '\r':
if(!(glutGetModifiers() & GLUT_ACTIVE_ALT)) {
break;
}
case 'f':
fullscr ^= 1;
if(fullscr) {
prev_xsz = glutGet(GLUT_WINDOW_WIDTH);
prev_ysz = glutGet(GLUT_WINDOW_HEIGHT);
glutFullScreen();
} else {
glutReshapeWindow(prev_xsz, prev_ysz);
}
break;
}
}
void skeypress(int key, int x, int y)
{
switch(key) {
case GLUT_KEY_F1:
help ^= 1;
glutPostRedisplay();
default:
break;
}
}
void mouse(int bn, int st, int x, int y)
{
int bidx = bn - GLUT_LEFT_BUTTON;
bnstate[bidx] = st == GLUT_DOWN;
mouse_x = x;
mouse_y = y;
}
void motion(int x, int y)
{
int dx = x - mouse_x;
int dy = y - mouse_y;
mouse_x = x;
mouse_y = y;
if(!(dx | dy)) return;
if(bnstate[0]) {
cam_theta += dx * 0.5;
cam_phi += dy * 0.5;
if(cam_phi < -90) cam_phi = -90;
if(cam_phi > 90) cam_phi = 90;
glutPostRedisplay();
}
if(bnstate[1]) {
float up[3], right[3];
float theta = cam_theta * M_PI / 180.0f;
float phi = cam_phi * M_PI / 180.0f;
up[0] = -sin(theta) * sin(phi);
up[1] = -cos(phi);
up[2] = cos(theta) * sin(phi);
right[0] = cos(theta);
right[1] = 0;
right[2] = sin(theta);
cam_pan[0] += (right[0] * dx + up[0] * dy) * 0.01;
cam_pan[1] += up[1] * dy * 0.01;
cam_pan[2] += (right[2] * dx + up[2] * dy) * 0.01;
glutPostRedisplay();
}
if(bnstate[2]) {
cam_dist += dy * 0.1;
if(cam_dist < 0) cam_dist = 0;
glutPostRedisplay();
}
}

View File

@ -0,0 +1,740 @@
/* CallbackMaker.c */
/*
* Program to invoke all the callbacks that "freeglut" supports
*/
#include <GL/freeglut.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
static int sequence_number = 0 ;
#define CALLBACKMAKER_N_WINDOWS 4
int windows[CALLBACKMAKER_N_WINDOWS] = {0};
/* define status vars showing whether given callback has been called for given window */
#define CALLBACK_CALLED_VAR(name) int name##_called[CALLBACKMAKER_N_WINDOWS] = {0}
#define CALLBACK_0V(name) int name##_seq[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_CALLED_VAR(name)
#define CALLBACK_1V(name,field) int name##_##field[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_0V(name)
#define CALLBACK_2V(name,field1,field2) int name##_##field2[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_1V(name,field1)
#define CALLBACK_3V(name,field1,field2,field3) int name##_##field3[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_2V(name,field1,field2)
#define CALLBACK_4V(name,field1,field2,field3,field4) int name##_##field4[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_3V(name,field1,field2,field3)
#define CALLBACK_5V(name,field1,field2,field3,field4,field5) int name##_##field5[CALLBACKMAKER_N_WINDOWS] = {-1}; CALLBACK_4V(name,field1,field2,field3,field4)
CALLBACK_2V(reshape,width,height);
CALLBACK_2V(position,top,left);
CALLBACK_1V(visibility,vis);
CALLBACK_1V(windowStatus,state);
CALLBACK_4V(key,key,x,y,mod);
CALLBACK_4V(keyup,key,x,y,mod);
CALLBACK_4V(special,key,x,y,mod);
CALLBACK_4V(specialup,key,x,y,mod);
CALLBACK_4V(joystick,a,b,c,d);
CALLBACK_5V(mouse,button,updown,x,y,mod);
CALLBACK_5V(mousewheel,number,direction,x,y,mod);
CALLBACK_3V(motion,x,y,mod);
CALLBACK_3V(passivemotion,x,y,mod);
CALLBACK_1V(entry,state);
CALLBACK_0V(close);
/* menudestroy is registered on each menu, not a window */
int menudestroy_called = 0;
/* menustatus and menustate are global callbacks, set for all menus at the same time */
int menustatus_called = 0;
int menustate_called = 0;
#define STRING_LENGTH 10
static void
bitmapPrintf (const char *fmt, ...)
{
static char buf[256];
va_list args;
va_start(args, fmt);
#if defined(WIN32) && !defined(__CYGWIN__)
(void) _vsnprintf (buf, sizeof(buf), fmt, args);
#else
(void) vsnprintf (buf, sizeof(buf), fmt, args);
#endif
va_end(args);
glutBitmapString ( GLUT_BITMAP_HELVETICA_12, (unsigned char*)buf ) ;
}
static int
getWindowAndIdx(int *winIdx)
{
int window = glutGetWindow();
if (winIdx)
(*winIdx) = window==windows[0] ? 0 :
window==windows[1] ? 1 :
window==windows[2] ? 2 : 3;
return window;
}
static void
Mod2Text(int mods, char *text)
{
if (mods&GLUT_ACTIVE_CTRL)
strcat(text,"CTRL");
if (mods&GLUT_ACTIVE_SHIFT)
{
if (text[0])
strcat(text,"+SHIFT");
else
strcat(text,"SHIFT");
}
if (mods&GLUT_ACTIVE_ALT)
{
if (text[0])
strcat(text,"+ALT");
else
strcat(text,"ALT");
}
if (!text[0])
strcat(text,"none");
}
static void
Display(void)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
glClear ( GL_COLOR_BUFFER_BIT );
glDisable ( GL_DEPTH_TEST );
glMatrixMode ( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
glOrtho(0, glutGet ( GLUT_WINDOW_WIDTH ),
0, glutGet ( GLUT_WINDOW_HEIGHT ), -1, 1 );
glMatrixMode ( GL_MODELVIEW );
glPushMatrix ();
glLoadIdentity ();
glColor3ub ( 0, 0, 0 );
glRasterPos2i ( 10, glutGet ( GLUT_WINDOW_HEIGHT ) - 20 ); /* 10pt margin above 10pt letters */
if ( entry_called[winIdx] )
{
bitmapPrintf ( "Entry %d: %d\n", entry_seq[winIdx], entry_state[winIdx] );
}
if ( visibility_called[winIdx] )
{
bitmapPrintf ( "Visibility %d: %d\n", visibility_seq[winIdx], visibility_vis[winIdx] );
}
if ( windowStatus_called[winIdx] )
{
bitmapPrintf ( "WindowStatus %d: %d\n", windowStatus_seq[winIdx], windowStatus_state[winIdx] );
}
if ( reshape_called[winIdx] )
{
bitmapPrintf ( "Reshape %d: %d %d\n", reshape_seq[winIdx], reshape_width[winIdx], reshape_height[winIdx] );
}
if ( position_called[winIdx] )
{
bitmapPrintf ( "Position %d: %d %d\n", position_seq[winIdx], position_left[winIdx], position_top[winIdx] );
}
if ( key_called[winIdx] )
{
char mods[50] = {0};
Mod2Text(key_mod[winIdx],mods);
bitmapPrintf ( "Key %d: %d(%c) %d %d (mod: %s)\n", key_seq[winIdx], key_key[winIdx], key_key[winIdx], key_x[winIdx], key_y[winIdx], mods );
}
if ( keyup_called[winIdx] )
{
char mods[50] = {0};
Mod2Text(keyup_mod[winIdx],mods);
bitmapPrintf ( "Key Up %d: %d(%c) %d %d (mod: %s)\n", keyup_seq[winIdx], keyup_key[winIdx], keyup_key[winIdx], keyup_x[winIdx], keyup_y[winIdx], mods );
}
if ( special_called[winIdx] )
{
char mods[50] = {0};
Mod2Text(special_mod[winIdx],mods);
bitmapPrintf ( "Special %d: %d(%c) %d %d (mod: %s)\n", special_seq[winIdx], special_key[winIdx], special_key[winIdx], special_x[winIdx], special_y[winIdx], mods );
}
if ( specialup_called[winIdx] )
{
char mods[50] = {0};
Mod2Text(specialup_mod[winIdx],mods);
bitmapPrintf ( "Special Up %d: %d(%c) %d %d (mod: %s)\n", specialup_seq[winIdx], specialup_key[winIdx], specialup_key[winIdx], specialup_x[winIdx], specialup_y[winIdx], mods );
}
if ( joystick_called[winIdx] )
{
bitmapPrintf ( "Joystick %d: %d %d %d %d\n", joystick_seq[winIdx], joystick_a[winIdx], joystick_b[winIdx], joystick_c[winIdx], joystick_d[winIdx] );
}
if ( mouse_called[winIdx] )
{
char mods[50] = {0};
Mod2Text(mouse_mod[winIdx],mods);
bitmapPrintf ( "Mouse %d: %d %d %d %d (mod: %s)\n", mouse_seq[winIdx], mouse_button[winIdx], mouse_updown[winIdx], mouse_x[winIdx], mouse_y[winIdx], mods );
}
if ( mousewheel_called[winIdx] )
{
char mods[50] = {0};
Mod2Text(mousewheel_mod[winIdx],mods);
bitmapPrintf ( "Mouse Wheel %d: %d %d %d %d (mod: %s)\n", mousewheel_seq[winIdx], mousewheel_number[winIdx], mousewheel_direction[winIdx], mousewheel_x[winIdx], mousewheel_y[winIdx], mods );
}
if ( motion_called[winIdx] )
{
char mods[50] = {0};
Mod2Text(motion_mod[winIdx],mods);
bitmapPrintf ( "Motion %d: %d %d (mod: %s)\n", motion_seq[winIdx], motion_x[winIdx], motion_y[winIdx], mods );
}
if ( passivemotion_called[winIdx] )
{
char mods[50] = {0};
Mod2Text(passivemotion_mod[winIdx],mods);
bitmapPrintf ( "Passive Motion %d: %d %d (mod: %s)\n", passivemotion_seq[winIdx], passivemotion_x[winIdx], passivemotion_y[winIdx], mods );
}
glMatrixMode ( GL_PROJECTION );
glPopMatrix ();
glMatrixMode ( GL_MODELVIEW );
glPopMatrix ();
glEnable ( GL_DEPTH_TEST );
printf ( "%6d Window %d Display Callback\n",
++sequence_number, window ) ;
glutSwapBuffers();
}
static void
Warning(const char *fmt, va_list ap)
{
printf("%6d Warning callback:\n",++sequence_number);
/* print warning message */
vprintf(fmt, ap);
}
static void
Error(const char *fmt, va_list ap)
{
char dummy_string[STRING_LENGTH];
printf("%6d Error callback:\n",++sequence_number);
/* print warning message */
vprintf(fmt, ap);
printf("\n");
/* terminate program, after pause for input so user can see */
printf ( "Please enter something to exit: " );
fgets ( dummy_string, STRING_LENGTH, stdin );
/* Call exit directly as freeglut is messed
* up internally when an error is called.
*/
exit(1);
}
static void
Reshape(int width, int height)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Reshape Callback: %d %d\n",
++sequence_number, window, width, height ) ;
reshape_called[winIdx] = 1 ;
reshape_width[winIdx] = width ;
reshape_height[winIdx] = height ;
reshape_seq[winIdx] = sequence_number ;
glViewport(0,0,width,height);
glutPostRedisplay () ;
}
static void
Position(int left, int top)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Position Callback: %d %d\n",
++sequence_number, window, left, top ) ;
position_called[winIdx] = 1 ;
position_left[winIdx] = left ;
position_top[winIdx] = top ;
position_seq[winIdx] = sequence_number ;
glutPostRedisplay () ;
}
static void
Key(unsigned char key, int x, int y)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Keyboard Callback: %d %d %d\n",
++sequence_number, window, key, x, y ) ;
key_called[winIdx] = 1 ;
key_key[winIdx] = key ;
key_x[winIdx] = x ;
key_y[winIdx] = y ;
key_seq[winIdx] = sequence_number ;
key_mod[winIdx] = glutGetModifiers() ;
glutPostRedisplay () ;
}
static void
KeyUp(unsigned char key, int x, int y)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Key Release Callback: %d %d %d\n",
++sequence_number, window, key, x, y ) ;
keyup_called[winIdx] = 1 ;
keyup_key[winIdx] = key ;
keyup_x[winIdx] = x ;
keyup_y[winIdx] = y ;
keyup_seq[winIdx] = sequence_number ;
keyup_mod[winIdx] = glutGetModifiers() ;
glutPostRedisplay () ;
}
static void
Special(int key, int x, int y)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Special Key Callback: %d %d %d\n",
++sequence_number, window, key, x, y ) ;
special_called[winIdx] = 1 ;
special_key[winIdx] = key ;
special_x[winIdx] = x ;
special_y[winIdx] = y ;
special_seq[winIdx] = sequence_number ;
special_mod[winIdx] = glutGetModifiers() ;
glutPostRedisplay () ;
}
static void
SpecialUp(int key, int x, int y)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Special Key Release Callback: %d %d %d\n",
++sequence_number, window, key, x, y ) ;
specialup_called[winIdx] = 1 ;
specialup_key[winIdx] = key ;
specialup_x[winIdx] = x ;
specialup_y[winIdx] = y ;
specialup_seq[winIdx] = sequence_number ;
specialup_mod[winIdx] = glutGetModifiers() ;
glutPostRedisplay () ;
}
static void
Joystick( unsigned int a, int b, int c, int d) /* Need meaningful names */
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Joystick Callback: %d %d %d %d\n",
++sequence_number, window, a, b, c, d ) ;
joystick_called[winIdx] = 1 ;
joystick_a[winIdx] = a ;
joystick_b[winIdx] = b ;
joystick_c[winIdx] = c ;
joystick_d[winIdx] = d ;
joystick_seq[winIdx] = sequence_number ;
glutPostRedisplay () ;
}
static void
Mouse(int button, int updown, int x, int y)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Mouse Click Callback: %d %d %d %d\n",
++sequence_number, window, button, updown, x, y ) ;
mouse_called[winIdx] = 1 ;
mouse_button[winIdx] = button ;
mouse_updown[winIdx] = updown ;
mouse_x[winIdx] = x ;
mouse_y[winIdx] = y ;
mouse_seq[winIdx] = sequence_number ;
mouse_mod[winIdx] = glutGetModifiers() ;
glutPostRedisplay () ;
}
static void
MouseWheel(int wheel_number, int direction, int x, int y)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Mouse Wheel Callback: %d %d %d %d\n",
++sequence_number, window, wheel_number, direction, x, y ) ;
mousewheel_called[winIdx] = 1 ;
mousewheel_number[winIdx] = wheel_number ;
mousewheel_direction[winIdx] = direction ;
mousewheel_x[winIdx] = x ;
mousewheel_y[winIdx] = y ;
mousewheel_seq[winIdx] = sequence_number ;
mousewheel_mod[winIdx] = glutGetModifiers() ;
glutPostRedisplay () ;
}
static void
Motion(int x, int y)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Mouse Motion Callback: %d %d\n",
++sequence_number, window, x, y ) ;
motion_called[winIdx] = 1 ;
motion_x[winIdx] = x ;
motion_y[winIdx] = y ;
motion_seq[winIdx] = sequence_number ;
motion_mod[winIdx] = glutGetModifiers() ;
glutPostRedisplay () ;
}
static void
PassiveMotion(int x, int y)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Mouse Passive Motion Callback: %d %d\n",
++sequence_number, window, x, y ) ;
passivemotion_called[winIdx] = 1 ;
passivemotion_x[winIdx] = x ;
passivemotion_y[winIdx] = y ;
passivemotion_seq[winIdx] = sequence_number ;
passivemotion_mod[winIdx] = glutGetModifiers() ;
glutPostRedisplay () ;
}
static void
Entry(int state)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Entry Callback: %d\n",
++sequence_number, window, state ) ;
entry_called[winIdx] = 1 ;
entry_seq[winIdx] = sequence_number;
entry_state[winIdx] = state;
glutPostRedisplay () ;
}
static void
Close(void)
{
int window = getWindowAndIdx(NULL);
printf ( "%6d Window %d Close Callback\n",
++sequence_number, window ) ;
}
static void
OverlayDisplay(void)
{
int window = getWindowAndIdx(NULL);
printf ( "%6d Window %d OverlayDisplay Callback\n",
++sequence_number, window ) ;
glutPostRedisplay () ;
}
static void
Visibility(int vis)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d Visibility Callback: %d\n",
++sequence_number, window, vis ) ;
visibility_called[winIdx] = 1 ;
visibility_vis[winIdx] = vis ;
visibility_seq[winIdx] = sequence_number ;
glutPostRedisplay () ;
}
static void
WindowStatus(int state)
{
int winIdx;
int window = getWindowAndIdx(&winIdx);
printf ( "%6d Window %d WindowStatus Callback: %d\n",
++sequence_number, window, state ) ;
windowStatus_called[winIdx] = 1 ;
windowStatus_state[winIdx] = state ;
windowStatus_seq[winIdx] = sequence_number ;
glutPostRedisplay () ;
}
static void
SpaceMotion(int x, int y, int z)
{
int window = getWindowAndIdx(NULL);
printf ( "%6d Window %d SpaceMotion Callback: %d %d %d\n",
++sequence_number, window, x, y, z ) ;
glutPostRedisplay () ;
}
static void
SpaceRotation(int x, int y, int z)
{
int window = getWindowAndIdx(NULL);
printf ( "%6d Window %d SpaceRotation Callback: %d %d %d\n",
++sequence_number, window, x, y, z ) ;
glutPostRedisplay () ;
}
static void
SpaceButton(int button, int updown)
{
int window = getWindowAndIdx(NULL);
printf ( "%6d Window %d SpaceButton Callback: %d %d\n",
++sequence_number, window, button, updown ) ;
glutPostRedisplay () ;
}
static void
Dials(int x, int y)
{
int window = getWindowAndIdx(NULL);
printf ( "%6d Window %d Dials Callback: %d %d\n",
++sequence_number, window, x, y ) ;
glutPostRedisplay () ;
}
static void
ButtonBox(int button, int updown)
{
int window = getWindowAndIdx(NULL);
printf ( "%6d Window %d ButtonBox Callback: %d %d\n",
++sequence_number, window, button, updown ) ;
glutPostRedisplay () ;
}
static void
TabletMotion(int x, int y)
{
int window = getWindowAndIdx(NULL);
printf ( "%6d Window %d TabletMotion Callback: %d %d\n",
++sequence_number, window, x, y ) ;
glutPostRedisplay () ;
}
static void
TabletButton(int button, int updown, int x, int y)
{
int window = getWindowAndIdx(NULL);
printf ( "%6d Window %d TabletButton Callback: %d %d %d %d\n",
++sequence_number, window, button, updown, x, y ) ;
glutPostRedisplay () ;
}
static void
MenuCallback ( int value )
{
int menu = glutGetMenu();
int window = getWindowAndIdx(NULL);
printf( "%6d Menu %d MenuCallback for menu opened in Window %d - value is %d\n",
++sequence_number, menu, window, value );
}
static void
MenuDestroy( void )
{
int menu = glutGetMenu();
menudestroy_called = 1 ;
printf ( "%6d Menu %d MenuDestroy Callback\n",
++sequence_number, menu ) ;
}
static void
MenuStatus( int status, int x, int y )
{
/* Menu and window for which this event is triggered are current when the callback is called */
int menu = glutGetMenu();
int window = getWindowAndIdx(NULL);
menustatus_called = 1 ;
printf ( "%6d Menu %d MenuStatus Callback in Window %d: %d %d %d\n",
++sequence_number, menu, window, status, x, y ) ;
glutPostRedisplay () ;
}
static void
MenuState( int status )
{
/* Menu and window for which this event is triggered are current when the callback is called */
int menu = glutGetMenu();
int window = getWindowAndIdx(NULL);
menustate_called = 1 ;
printf ( "%6d Menu %d MenuState Callback in Window %d: %d\n",
++sequence_number, menu, window, status) ;
glutPostRedisplay () ;
}
static void Idle ( void )
{
++sequence_number ;
}
static void SetWindowCallbacks( int first )
{
/* All these callbacks are set for only the current window */
glutDisplayFunc( Display );
glutReshapeFunc( Reshape );
glutPositionFunc( Position );
glutKeyboardFunc( Key );
glutSpecialFunc( Special );
glutKeyboardUpFunc( KeyUp );
glutSpecialUpFunc( SpecialUp );
if (first)
glutJoystickFunc( Joystick, 100 );
glutMouseFunc ( Mouse ) ;
glutMouseWheelFunc ( MouseWheel ) ;
glutMotionFunc ( Motion ) ;
glutPassiveMotionFunc ( PassiveMotion ) ;
glutEntryFunc ( Entry ) ;
glutCloseFunc ( Close ) ;
glutOverlayDisplayFunc ( OverlayDisplay ) ;
glutSpaceballMotionFunc ( SpaceMotion ) ;
glutSpaceballRotateFunc ( SpaceRotation ) ;
glutSpaceballButtonFunc ( SpaceButton ) ;
glutButtonBoxFunc ( ButtonBox ) ;
glutDialsFunc ( Dials ) ;
glutTabletMotionFunc ( TabletMotion ) ;
glutTabletButtonFunc ( TabletButton ) ;
/* glutVisibilityFunc is deprecated in favor of glutWindowStatusFunc, which provides more detail.
* Setting one of these overwrites the other (see docs).
*/
glutVisibilityFunc ( Visibility ); /* This will thus never be called, as glutWindowStatusFunc is set afterwards */
glutWindowStatusFunc ( WindowStatus ) ;
}
int
main(int argc, char *argv[])
{
char dummy_string[STRING_LENGTH];
int subMenuA, subMenuB;
glutInitWarningFunc(Warning);
glutInitErrorFunc(Error);
glutInitWindowSize(500, 250);
glutInitWindowPosition ( 140, 140 );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );
glutInit(&argc, argv);
/* global setting: mainloop does not return when a window is closed, only returns when all windows are closed */
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_CONTINUE_EXECUTION);
/* global setting: repeated keys generating by keeping the key pressed down are passed on to the keyboard callback */
/* There are two functions to control this behavior, glutSetKeyRepeat to set it globally, and glutIgnoreKeyRepeat to set it per window.
* These two interact however. If key repeat is globally switched off (glutSetKeyRepeat(GLUT_KEY_REPEAT_OFF)), it cannot be overridden
* (switched back on) for a specific window with glutIgnoreKeyRepeat. However, if key repeat is globally switched on
* (glutSetKeyRepeat(GLUT_KEY_REPEAT_ON)), it can be overridden (switched off) with glutIgnoreKeyRepeat on a per-window basis. That is
* what we demonstrate here.
*/
glutSetKeyRepeat(GLUT_KEY_REPEAT_ON);
/* Set other global callback (global as in not associated with any specific menu or window) */
glutIdleFunc ( Idle );
glutMenuStatusFunc ( MenuStatus );
glutMenuStateFunc ( MenuState ); /* Note that glutMenuStatusFunc is an enhanced version of the deprecated glutMenuStateFunc. */
/* Open first window */
windows[0] = glutCreateWindow( "Callback Demo" );
printf ( "Creating window %d as 'Callback Demo'\n", windows[0] ) ;
glClearColor(1.0, 1.0, 1.0, 1.0);
/* callbacks, settings and menus for this window */
SetWindowCallbacks( 1 );
glutIgnoreKeyRepeat(GL_TRUE);
glutSetIconTitle("Icon Test - Callback Demo");
subMenuA = glutCreateMenu( MenuCallback );
glutAddMenuEntry( "Sub menu A1 (01)", 11 );
glutAddMenuEntry( "Sub menu A2 (02)", 12 );
glutAddMenuEntry( "Sub menu A3 (03)", 13 );
glutMenuDestroyFunc ( MenuDestroy ); /* callback specific to this menu */
/* Change font for this menu */
glutSetMenuFont(subMenuA, GLUT_BITMAP_HELVETICA_12);
subMenuB = glutCreateMenu( MenuCallback );
glutAddMenuEntry( "Sub menu B1 (04)", 14 );
glutAddMenuEntry( "Sub menu B2 (05)", 15 );
glutAddMenuEntry( "Sub menu B3 (06)", 16 );
glutAddSubMenu( "Going to sub menu A", subMenuA );
glutMenuDestroyFunc ( MenuDestroy ); /* callback specific to this menu */
glutSetMenuFont(subMenuB, GLUT_BITMAP_9_BY_15);
glutCreateMenu( MenuCallback );
glutAddMenuEntry( "Entry one", 21 );
glutAddMenuEntry( "Entry two", 22 );
glutAddMenuEntry( "Entry three", 23 );
glutAddMenuEntry( "Entry four", 24 );
glutAddMenuEntry( "Entry five", 25 );
glutAddSubMenu( "Enter sub menu A", subMenuA );
glutAddSubMenu( "Enter sub menu B", subMenuB );
glutMenuDestroyFunc ( MenuDestroy ); /* callback specific to this menu */
glutAttachMenu( GLUT_LEFT_BUTTON );
/* Position second window right next to the first */
glutInitWindowPosition ( 140+500+2*glutGet(GLUT_WINDOW_BORDER_WIDTH), 140 );
glutInitWindowSize(600, 600);
windows[1] = glutCreateWindow( "Second Window" );
printf ( "Creating window %d as 'Second Window'\n", windows[1] ) ;
glClearColor(1.0, 1.0, 1.0, 1.0);
/* callbacks, settings and menus for this window */
SetWindowCallbacks( 0 );
glutIgnoreKeyRepeat(GL_TRUE);
glutSetMenu(subMenuB);
glutAttachMenu( GLUT_RIGHT_BUTTON );
/* position a third window as a subwindow of the second */
windows[2] = glutCreateSubWindow(windows[1],0,300,600,300);
printf ( "Creating window %d as subwindow to 'Second Window'\n", windows[2] ) ;
glClearColor(0.7f, 0.7f, 0.7f, 1.0);
/* callbacks, settings and menus for this window */
SetWindowCallbacks( 0 );
glutSetCursor(GLUT_CURSOR_CROSSHAIR); /* Cursors are per window */
glutSetMenu(subMenuA);
glutAttachMenu( GLUT_RIGHT_BUTTON );
/* position a fourth window as a subsubwindow (grandchild) of the second */
windows[3] = glutCreateSubWindow(windows[2],300,0,300,300);
printf ( "Creating window %d as subsubwindow to 'Second Window'\n", windows[3] ) ;
glClearColor(0.4f, 0.4f, 0.4f, 1.0);
/* callbacks and menus for this window */
SetWindowCallbacks( 0 );
glutSetCursor(GLUT_CURSOR_INHERIT); /* Inherit cursor look from parent (this is default on window creation) - comment the below to see in action */
glutSetCursor(GLUT_CURSOR_CYCLE);
printf ( "Please enter something to continue: " );
fgets ( dummy_string, STRING_LENGTH, stdin );
glutMainLoop();
printf ( "Back from the 'freeglut' main loop\n" ) ;
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,342 @@
/* fractals.c */
/*
* Program to draw a fractal by Michael Barnsley's deterministic algorithm.
* Algorithm:
* (1) Define the affine transformations (of the form r(i+1) = A r(i) + b )
* (2) Find the stationary point for each transformation
* (3) To draw:
* - If you are at the lowest level, draw lines connecting all the stationary points
* - If not, call the draw function recursively with each affine transformation applied
*/
/*
* User Commands:
* +,- - increment/decrement number of levels
* PgUp, PgDn - increase/decrease scaling
* Arrow keys - translate viewing section
* r - reset view
* Escape - quit
*/
#include <GL/freeglut.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define FGH_PI 3.14159265358979323846
typedef struct
{
double a00, a01, a10, a11 ; /* Transformation matrix */
double b0, b1 ; /* Constant vector added on */
double statx, staty ; /* Coordinates of the stationary point */
}
AffineTrans ;
/* Number of levels to draw the fractal */
static int num_levels = 4 ;
/* The definition of the fractal */
static int num_trans ;
static AffineTrans *affine ;
/* Flag telling us to keep executing the main loop */
static int continue_in_main_loop = 1;
/* the window title */
char window_title [ 80 ] ;
/* The amount the view is translated and scaled */
double xwin = 0.0, ywin = 0.0 ;
double scale_factor = 1.0 ;
static void draw_level ( int num, double m00, double m01, double m10, double m11, double n0, double n1 )
{
/* Draw a fractal transformed by "M", "N" as passed in */
int i ;
if ( num == 0 )
{
double x0 = m00 * affine[0].statx + m01 * affine[0].staty + n0 ;
double y0 = m10 * affine[0].statx + m11 * affine[0].staty + n1 ;
for ( i = 1; i < num_trans; i++ )
{
double x1 = m00 * affine[i].statx + m01 * affine[i].staty + n0 ;
double y1 = m10 * affine[i].statx + m11 * affine[i].staty + n1 ;
glVertex2d ( x0, y0 ) ;
glVertex2d ( x1, y1 ) ;
x0 = x1 ;
y0 = y1 ;
}
}
else
{
/* Map each affine transformation in the fractal through the one passed in and call "draw_level" */
for ( i = 0; i < num_trans; i++ )
{
draw_level ( num-1, m00*affine[i].a00+m01*affine[i].a10, m00*affine[i].a01+m01*affine[i].a11,
m10*affine[i].a00+m11*affine[i].a10, m10*affine[i].a01+m11*affine[i].a11,
m00*affine[i].b0 +m01*affine[i].b1 + n0, m10*affine[i].b0 +m11*affine[i].b1 + n1 ) ;
}
}
}
static void
Display(void)
{
glClear( GL_COLOR_BUFFER_BIT );
/* the curve */
glPushMatrix();
glScalef(2.5, 2.5, 2.5);
glColor4f(0.0, 0.0, 0.0, 1.0);
glBegin ( GL_LINES ) ;
draw_level ( num_levels, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 );
glEnd () ;
glPopMatrix();
glutSwapBuffers();
}
static void
Reshape(int width, int height)
{
float ar;
glViewport ( 0, 0, width, height ) ;
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity();
ar = (float) width / (float) height ;
if( ar > 1 )
glFrustum ( -ar, ar, -1.0, 1.0, 2.0, 100.0 ) ;
else
glFrustum ( -1.0, 1.0, -1/ar, 1/ar, 2.0, 100.0 );
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity () ;
xwin = -1.0 ;
ywin = 0.0 ;
glTranslated ( xwin, ywin, -5.0 ) ;
}
static void
Key(unsigned char key, int x, int y)
{
int need_redisplay = 1;
switch (key) {
case 27: /* Escape key */
continue_in_main_loop = 0 ;
break;
case '+' :
++num_levels ;
break ;
case '-' :
if ( num_levels > 0 )
--num_levels ;
break ;
case 'r' : case 'R' :
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity();
xwin = -1.0 ;
ywin = 0.0 ;
glTranslated ( xwin, ywin, -5.0 ) ;
break ;
default:
need_redisplay = 0;
break;
}
if (need_redisplay)
glutPostRedisplay();
}
static void
Special(int key, int x, int y)
{
int need_redisplay = 1;
switch (key) {
case GLUT_KEY_UP :
glMatrixMode ( GL_MODELVIEW ) ;
ywin += 0.1 * scale_factor ;
glTranslated ( 0.0, 0.1 * scale_factor, 0.0 ) ;
break ;
case GLUT_KEY_DOWN :
glMatrixMode ( GL_MODELVIEW ) ;
ywin -= 0.1 * scale_factor ;
glTranslated ( 0.0, -0.1 * scale_factor, 0.0 ) ;
break ;
case GLUT_KEY_LEFT :
glMatrixMode ( GL_MODELVIEW ) ;
xwin -= 0.1 * scale_factor ;
glTranslated ( -0.1 * scale_factor, 0.0, 0.0 ) ;
break ;
case GLUT_KEY_RIGHT :
glMatrixMode ( GL_MODELVIEW ) ;
xwin += 0.1 * scale_factor ;
glTranslated ( 0.1 * scale_factor, 0.0, 0.0 ) ;
break ;
case GLUT_KEY_PAGE_UP :
glMatrixMode ( GL_MODELVIEW ) ;
glTranslated ( -xwin, -ywin, 0.0 ) ;
glScaled ( 1.25, 1.25, 1.25 ) ;
glTranslated ( xwin, ywin, 0.0 ) ;
scale_factor *= 0.8 ;
break ;
case GLUT_KEY_PAGE_DOWN :
glMatrixMode ( GL_MODELVIEW ) ;
glTranslated ( -xwin, -ywin, 0.0 ) ;
glScaled ( 0.8, 0.8, 0.8 ) ;
glTranslated ( xwin, ywin, 0.0 ) ;
scale_factor *= 1.25 ;
break ;
default:
need_redisplay = 0;
break;
}
if (need_redisplay)
glutPostRedisplay();
}
static void
checkedFGets ( char *s, int size, FILE *stream )
{
if ( fgets ( s, size, stream ) == NULL ) {
fprintf ( stderr, "fgets failed\n");
exit ( EXIT_FAILURE );
}
}
void readConfigFile ( char *fnme )
{
FILE *fptr = fopen ( fnme, "rt" ) ;
int i ;
char inputline [ 256 ] ;
if ( fptr )
{
/* Read a header line */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
/* Read a comment line */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
/* Read the window title */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
/* We assume here that this line will not exceed 79 characters plus a
newline (window_title is 80 characters long). That'll cause a buffer
overflow. For a simple program like this, though, we're letting it
slide!
*/
sscanf ( inputline, "%[a-zA-Z0-9!@#$%^&*()+=/\\_-\" ]", window_title ) ;
/* Read a comment line */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
/* Read the number of affine transformations */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
sscanf ( inputline, "%d", &num_trans ) ;
affine = (AffineTrans *)malloc ( num_trans * sizeof(AffineTrans) ) ;
/* Read a comment line */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
for ( i = 0; i < num_trans; i++ )
{
/* Read an affine transformation definition */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
sscanf ( inputline, "%lf %lf %lf %lf %lf %lf", &affine[i].a00, &affine[i].a01,
&affine[i].a10, &affine[i].a11, &affine[i].b0, &affine[i].b1 ) ;
}
}
else /* No data file, set a default */
{
printf ( "ERROR opening file <%s>\n", fnme ) ;
strcpy ( window_title, "Koch Snowflake" ) ;
num_trans = 4 ;
affine = (AffineTrans *)malloc ( num_trans * sizeof(AffineTrans) ) ;
affine[0].a00 = 1/3. ; affine[0].a01 = 0.00 ; affine[0].a10 = 0.00 ; affine[0].a11 = 1/3. ;
affine[0].b0 = 0.0 ; affine[0].b1 = 0.0 ;
affine[1].a00 = 1/6. ; affine[1].a01 = -1/3.*sin(FGH_PI/3.) ; affine[1].a10 = 1/3.*sin(FGH_PI/3.) ; affine[1].a11 = 1/6. ;
affine[1].b0 = 1/3. ; affine[1].b1 = 0.0 ;
affine[2].a00 = 1/6. ; affine[2].a01 = -1/3.*sin(-FGH_PI/3.) ; affine[2].a10 = 1/3.*sin(-FGH_PI/3.) ; affine[2].a11 = 1/6. ;
affine[2].b0 = 0.5 ; affine[2].b1 = sqrt(3)/6. ;
affine[3].a00 = 1/3. ; affine[3].a01 = 0.00 ; affine[3].a10 = 0.00 ; affine[3].a11 = 1/3. ;
affine[3].b0 = 2/3. ; affine[3].b1 = 0.0 ;
}
for ( i = 0; i < num_trans; i++ )
{
double m00, m01, m10, m11 ; /* Matrix "I" minus "A" */
double determ ; /* Determinant of this matrix */
/* Calculate the stationary point */
m00 = 1.0 - affine[i].a00 ;
m01 = - affine[i].a01 ;
m10 = - affine[i].a10 ;
m11 = 1.0 - affine[i].a11 ;
determ = m00 * m11 - m01 * m10 ;
if ( fabs ( determ ) > 1.e-6 )
{
affine[i].statx = ( m11 * affine[i].b0 - m01 * affine[i].b1 ) / determ ;
affine[i].staty = ( -m10 * affine[i].b0 + m00 * affine[i].b1 ) / determ ;
}
else
affine[i].statx = affine[i].staty = 0.0 ;
}
}
int
main(int argc, char *argv[])
{
glutInitWindowSize(500, 250);
glutInitWindowPosition ( 140, 140 );
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );
glutInit(&argc, argv);
if ( argc > 1 )
readConfigFile ( argv[1] ) ;
else
readConfigFile ( "fractals.dat" ) ;
glutCreateWindow( window_title );
glClearColor(1.0, 1.0, 1.0, 1.0);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutSpecialFunc(Special);
glutDisplayFunc(Display);
#ifdef WIN32
#endif
while ( continue_in_main_loop )
glutMainLoopEvent();
printf ( "Back from the 'freeglut' main loop\n" ) ;
return 0; /* ANSI C requires main to return int. */
}

View File

@ -0,0 +1,10 @@
Koch Snowflake Fractal
Title of window
"Koch Snowflake"
Number of transformations
4
A00 A01 A10 A11 B0 B1
0.33333 0.0 0.0 0.33333 0.0 0.0
0.16667 -.28868 0.28868 0.16667 0.33333 0.0
0.16667 0.28868 -.28868 0.16667 0.5 0.28868
0.33333 0.0 0.0 0.33333 0.66667 0.0

View File

@ -0,0 +1,10 @@
Koch Snowflake Fractal
Title of window
"Koch Snowflake"
Number of transformations
4
A00 A01 A10 A11 B0 B1
0.33333 0.0 0.0 0.33333 0.0 0.0
0.16667 -.28868 0.28868 0.16667 0.33333 0.0
0.16667 0.28868 -.28868 0.16667 0.5 0.28868
0.33333 0.0 0.0 0.33333 0.66667 0.0

View File

@ -0,0 +1,393 @@
/* fractals_random.c */
/* This demo shows a single-buffering "freeglut" example. */
/*
* Program to draw a fractal by Michael Barnsley's stochastic algorithm.
* Algorithm:
* (1) Define the affine transformations (of the form r(i+1) = A r(i) + b )
* (2) Find the stationary point for the first transformation
* (3) To draw:
* - Pick a random integer between 1 and the number of transformations (inclusive)
* - Send the current point through the transformation to create the new current point
* - Plot the new current point
*/
/*
* User Commands:
* PgUp, PgDn - increase/decrease scaling
* Arrow keys - translate viewing section
* r - reset view
* Escape - quit
*/
#include <GL/freeglut.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define FGH_PI 3.14159265358979323846
#ifdef _MSC_VER
/* DUMP MEMORY LEAKS */
#include <crtdbg.h>
#endif
typedef struct
{
double a00, a01, a10, a11 ; /* Transformation matrix */
double b0, b1 ; /* Constant vector added on */
double statx, staty ; /* Coordinates of the stationary point */
}
AffineTrans ;
/* Number of levels to draw the fractal */
static int num_levels = 0 ;
/* The definition of the fractal */
static int num_trans ;
static AffineTrans *affine ;
/* the window title */
char window_title [ 80 ] ;
/* The amount the view is translated */
double xwin = 0.0, ywin = 0.0 ;
double scale_factor = 1.0 ;
/* The current point */
double current_x = 0.0, current_y = 0.0 ;
/* Signals when a glClear is needed */
static GLboolean needClear = GL_TRUE;
static void draw_level ( int num, double m00, double m01, double m10, double m11, double n0, double n1 )
{
/* Draw a fractal transformed by "M", "N" as passed in */
int i ;
for ( i = 0; i < 10; i++ )
{
int random = ( rand( ) >> 10 ) % num_trans;
double new_x = affine[random].a00 * current_x + affine[random].a01 * current_y + affine[random].b0 ;
double new_y = affine[random].a10 * current_x + affine[random].a11 * current_y + affine[random].b1 ;
glVertex2d ( new_x, new_y ) ;
current_x = new_x ;
current_y = new_y ;
}
}
static void
Display(void)
{
if (needClear) {
glClear(GL_COLOR_BUFFER_BIT);
needClear = GL_FALSE;
}
/* the curve */
glPushMatrix();
glScaled(2.5, 2.5, 2.5);
glColor4f(0.0, 0.0, 0.0, 1.0);
glBegin ( GL_POINTS ) ;
draw_level ( num_levels, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 );
glEnd () ;
glPopMatrix();
glFlush();
glutPostRedisplay(); /* Needed so that this function will be called again */
}
static void
Reshape(int width, int height)
{
float ar;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
ar = (float) width / (float) height;
if( ar > 1 )
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
else
glFrustum(-1.0, 1.0, -1/ar, 1/ar, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
xwin = -1.0 ;
ywin = 0.0 ;
glTranslated(xwin, ywin, -5.0);
needClear = GL_TRUE;
}
static void
Key(unsigned char key, int x, int y)
{
int changed_settings = 1;
switch (key) {
case 27: /* Escape key */
glutLeaveMainLoop ();
break;
case 'r' : case 'R' :
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
xwin = -1.0 ;
ywin = 0.0 ;
glTranslated(xwin, ywin, -5.0);
break ;
default:
changed_settings = 0;
break;
}
if (changed_settings)
needClear = GL_TRUE;
glutPostRedisplay();
}
static void
Special(int key, int x, int y)
{
int changed_settings = 1;
switch (key) {
case GLUT_KEY_UP :
glMatrixMode(GL_MODELVIEW);
ywin += 0.1 * scale_factor ;
glTranslated(0.0, 0.1 * scale_factor, 0.0);
break ;
case GLUT_KEY_DOWN :
glMatrixMode(GL_MODELVIEW);
ywin -= 0.1 * scale_factor ;
glTranslated(0.0, -0.1 * scale_factor, 0.0);
break ;
case GLUT_KEY_LEFT :
glMatrixMode(GL_MODELVIEW);
xwin -= 0.1 * scale_factor ;
glTranslated(-0.1 * scale_factor, 0.0, 0.0);
break ;
case GLUT_KEY_RIGHT :
glMatrixMode(GL_MODELVIEW);
xwin += 0.1 * scale_factor ;
glTranslated(0.1 * scale_factor, 0.0, 0.0);
break ;
case GLUT_KEY_PAGE_UP :
glMatrixMode(GL_MODELVIEW);
glTranslated ( -xwin, -ywin, 0.0 ) ;
glScaled(1.25, 1.25, 1.25);
glTranslated ( xwin, ywin, 0.0 ) ;
scale_factor *= 0.8 ;
break ;
case GLUT_KEY_PAGE_DOWN :
glMatrixMode(GL_MODELVIEW);
glTranslated ( -xwin, -ywin, 0.0 ) ;
glScaled(0.8, 0.8, 0.8);
glTranslated ( xwin, ywin, 0.0 ) ;
scale_factor *= 1.25 ;
break ;
default:
changed_settings = 0;
break;
}
if (changed_settings)
needClear = GL_TRUE;
glutPostRedisplay();
}
static int mouse_x = 0, mouse_y = 0 ;
static int button_down = GLUT_DOWN ;
static void
Mouse ( int button, int updown, int x, int y )
{
button_down = updown ;
if ( updown == GLUT_DOWN )
{
mouse_x = x ;
mouse_y = y ;
}
}
static void
MouseMotion ( int x, int y )
{
int window_width = glutGet ( GLUT_WINDOW_WIDTH ) ;
int window_height = glutGet ( GLUT_WINDOW_HEIGHT ) ;
int window_size = ( window_width < window_height ) ? window_width : window_height ;
double delta_x = 5.0 * (double)(x - mouse_x) / (double)(window_size) ;
double delta_y = 5.0 * (double)(y - mouse_y) / (double)(window_size) ;
xwin += delta_x * scale_factor ;
ywin -= delta_y * scale_factor ;
glMatrixMode ( GL_MODELVIEW ) ;
glTranslated ( delta_x * scale_factor, -delta_y * scale_factor, 0.0 ) ;
needClear = GL_TRUE;
glutPostRedisplay();
mouse_x = x ;
mouse_y = y ;
}
static void
MouseWheel ( int wheel_number, int direction, int x, int y )
{
double scale = ( direction > 0 ) ? 1.25 : 0.8 ;
glMatrixMode ( GL_MODELVIEW ) ;
glTranslated ( -xwin, -ywin, 0.0 ) ;
glScaled ( scale, scale, scale ) ;
glTranslated ( xwin, ywin, 0.0 ) ;
scale_factor /= scale ;
needClear = GL_TRUE;
glutPostRedisplay();
}
static void
checkedFGets ( char *s, int size, FILE *stream )
{
if ( fgets ( s, size, stream ) == NULL ) {
fprintf ( stderr, "fgets failed\n");
exit ( EXIT_FAILURE );
}
}
void readConfigFile ( char *fnme )
{
FILE *fptr = fopen ( fnme, "rt" ) ;
int i ;
char inputline [ 256 ] ;
if ( fptr )
{
/* Read a header line */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
/* Read a comment line */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
/* Read the window title */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
/* We assume here that this line will not exceed 79 characters plus a
newline (window_title is 80 characters long). That'll cause a buffer
overflow. For a simple program like this, though, we're letting it
slide!
*/
sscanf ( inputline, "%[a-zA-Z0-9!@#$%^&*()+=/\\_-\" ]", window_title ) ;
/* Read a comment line */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
/* Read the number of affine transformations */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
sscanf ( inputline, "%d", &num_trans ) ;
affine = (AffineTrans *)malloc ( num_trans * sizeof(AffineTrans) ) ;
/* Read a comment line */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
for ( i = 0; i < num_trans; i++ )
{
/* Read an affine transformation definition */
checkedFGets ( inputline, sizeof ( inputline ), fptr ) ;
sscanf ( inputline, "%lf %lf %lf %lf %lf %lf", &affine[i].a00, &affine[i].a01,
&affine[i].a10, &affine[i].a11, &affine[i].b0, &affine[i].b1 ) ;
}
}
else /* No data file, set a default */
{
printf ( "ERROR opening file <%s>\n", fnme ) ;
strcpy ( window_title, "Koch Snowflake" ) ;
num_trans = 4 ;
affine = (AffineTrans *)malloc ( num_trans * sizeof(AffineTrans) ) ;
affine[0].a00 = 1/3. ; affine[0].a01 = 0.00 ; affine[0].a10 = 0.00 ; affine[0].a11 = 1/3. ;
affine[0].b0 = 0.0 ; affine[0].b1 = 0.0 ;
affine[1].a00 = 1/6. ; affine[1].a01 = -1/3.*sin(FGH_PI/3.) ; affine[1].a10 = 1/3.*sin(FGH_PI/3.) ; affine[1].a11 = 1/6. ;
affine[1].b0 = 1/3. ; affine[1].b1 = 0.0 ;
affine[2].a00 = 1/6. ; affine[2].a01 = -1/3.*sin(-FGH_PI/3.) ; affine[2].a10 = 1/3.*sin(-FGH_PI/3.) ; affine[2].a11 = 1/6. ;
affine[2].b0 = 0.5 ; affine[2].b1 = sqrt(3)/6. ;
affine[3].a00 = 1/3. ; affine[3].a01 = 0.00 ; affine[3].a10 = 0.00 ; affine[3].a11 = 1/3. ;
affine[3].b0 = 2/3. ; affine[3].b1 = 0.0 ;
}
for ( i = 0; i < num_trans; i++ )
{
double m00, m01, m10, m11 ; /* Matrix "I" minus "A" */
double determ ; /* Determinant of this matrix */
/* Calculate the stationary point */
m00 = 1.0 - affine[i].a00 ;
m01 = - affine[i].a01 ;
m10 = - affine[i].a10 ;
m11 = 1.0 - affine[i].a11 ;
determ = m00 * m11 - m01 * m10 ;
if ( fabs ( determ ) > 1.e-6 )
{
affine[i].statx = ( m11 * affine[i].b0 - m01 * affine[i].b1 ) / determ ;
affine[i].staty = ( -m10 * affine[i].b0 + m00 * affine[i].b1 ) / determ ;
}
else
affine[i].statx = affine[i].staty = 0.0 ;
}
}
int
main(int argc, char *argv[])
{
glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );
glutInitWindowSize(500, 250);
glutInitWindowPosition ( 140, 140 ) ;
glutInit(&argc, argv);
if ( argc > 1 )
readConfigFile ( argv[1] ) ;
else
readConfigFile ( "fractals.dat" ) ;
glutCreateWindow( window_title );
glClearColor(1.0, 1.0, 1.0, 1.0);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutSpecialFunc(Special);
glutDisplayFunc(Display);
glutMouseFunc(Mouse);
glutMotionFunc(MouseMotion);
glutMouseWheelFunc(MouseWheel);
glutMainLoop();
printf ( "Back from the 'freeglut' main loop\n" ) ;
free ( affine ) ;
#ifdef _MSC_VER
/* DUMP MEMORY LEAK INFORMATION */
_CrtDumpMemoryLeaks () ;
#endif
return 0; /* ANSI C requires main to return int. */
}

378
progs/demos/Lorenz/lorenz.c Normal file
View File

@ -0,0 +1,378 @@
/*
* Lorenz Strange Attractor
*
* Written by John F. Fay in honor of the "freeglut" 2.0.0 release in July 2003
*
* What it does:
* This program starts with two particles right next to each other. The particles
* move through a three-dimensional phase space governed by the following equations:
* dx/dt = sigma * ( y - x )
* dy/dt = r * x - y + x * z
* dz/dt = x * y + b * z
* These are the Lorenz equations and define the "Lorenz Attractor." Any two particles
* arbitrarily close together will move apart as time increases, but their tracks are
* confined within a region of the space.
*
* Commands:
* Arrow keys: Rotate the view
* PgUp, PgDn: Zoom in and out
* Mouse click: Center on the nearest point on a particle trajectory
*
* 'r'/'R': Reset the simulation
* 'm'/'M': Modify the Lorenz parameters (in the text window)
* 's'/'S': Stop (the advancement in time)
* 'g'/'G': Go
* <spacebar>: Single-step
* <Escape>: Quit
*/
/* Include Files */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#include <GL/freeglut.h>
#ifdef _MSC_VER
/* DUMP MEMORY LEAKS */
#include <crtdbg.h>
#endif
/************************************** Defined Constants ***************************************/
/* Number of points to draw in the curves */
#define NUM_POINTS 512
/* Angle to rotate when the user presses an arrow key */
#define ROTATION_ANGLE 5.0
/* Amount to scale bu when the user presses PgUp or PgDn */
#define SCALE_FACTOR 0.8
/*************************************** Global Variables ***************************************/
/* Lorenz Attractor variables */
double s0 = 10.0, r0 = 28.0, b0 = 8.0/3.0 ; /* Default Lorenz attactor parameters */
double time_step = 0.03 ; /* Time step in the simulation */
double sigma = 10.0, r = 28.0, b = 8.0/3.0 ; /* Lorenz attactor parameters */
double red_position[NUM_POINTS][3] ; /* Path of the red point */
double grn_position[NUM_POINTS][3] ; /* Path of the green point */
int array_index ; /* Position in *_position arrays of most recent point */
double distance = 0.0 ; /* Distance between the two points */
/* GLUT variables */
double yaw = 0.0, pit = 0.0 ; /* Euler angles of the viewing rotation */
double scale = 1.0 ; /* Scale factor */
double xcen = 0.0, ycen = 0.0, zcen = 0.0 ; /* Coordinates of the point looked at */
int animate = 1 ; /* 0 - stop, 1 = go, 2 = single-step */
/******************************************* Functions ******************************************/
/* The Lorenz Attractor */
void calc_deriv ( double position[3], double deriv[3] )
{
/* Calculate the Lorenz attractor derivatives */
deriv[0] = sigma * ( position[1] - position[0] ) ;
deriv[1] = ( r + position[2] ) * position[0] - position[1] ;
deriv[2] = -position[0] * position[1] - b * position[2] ;
}
void advance_in_time ( double time_step, double position[3], double new_position[3] )
{
/* Move a point along the Lorenz attractor */
double deriv0[3], deriv1[3], deriv2[3], deriv3[3] ;
int i ;
memcpy ( new_position, position, 3 * sizeof(double) ) ; /* Save the present values */
/* First pass in a Fourth-Order Runge-Kutta integration method */
calc_deriv ( position, deriv0 ) ;
for ( i = 0; i < 3; i++ )
new_position[i] = position[i] + 0.5 * time_step * deriv0[i] ;
/* Second pass */
calc_deriv ( new_position, deriv1 ) ;
for ( i = 0; i < 3; i++ )
new_position[i] = position[i] + 0.5 * time_step * deriv1[i] ;
/* Third pass */
calc_deriv ( position, deriv2 ) ;
for ( i = 0; i < 3; i++ )
new_position[i] = position[i] + time_step * deriv2[i] ;
/* Second pass */
calc_deriv ( new_position, deriv3 ) ;
for ( i = 0; i < 3; i++ )
new_position[i] = position[i] + 0.1666666666666666667 * time_step *
( deriv0[i] + 2.0 * ( deriv1[i] + deriv2[i] ) + deriv3[i] ) ;
}
static void
checkedFGets ( char *s, int size, FILE *stream )
{
if ( fgets ( s, size, stream ) == NULL ) {
fprintf ( stderr, "fgets failed\n");
exit ( EXIT_FAILURE );
}
}
/* GLUT callbacks */
#define INPUT_LINE_LENGTH 80
void key_cb ( unsigned char key, int x, int y )
{
int i ;
char inputline [ INPUT_LINE_LENGTH ] ;
switch ( key )
{
case 'r' : case 'R' : /* Reset the simulation */
/* Reset the Lorenz parameters */
sigma = s0 ;
b = b0 ;
r = r0 ;
/* Set an initial position */
red_position[0][0] = (double)rand() / (double)RAND_MAX ;
red_position[0][1] = (double)rand() / (double)RAND_MAX ;
red_position[0][2] = (double)rand() / (double)RAND_MAX ;
grn_position[0][0] = (double)rand() / (double)RAND_MAX ;
grn_position[0][1] = (double)rand() / (double)RAND_MAX ;
grn_position[0][2] = (double)rand() / (double)RAND_MAX ;
array_index = 0 ;
/* Initialize the arrays */
for ( i = 1; i < NUM_POINTS; i++ )
{
memcpy ( red_position[i], red_position[0], 3 * sizeof(double) ) ;
memcpy ( grn_position[i], grn_position[0], 3 * sizeof(double) ) ;
}
break ;
case 'm' : case 'M' : /* Modify the Lorenz parameters */
printf ( "Please enter new value for <sigma> (default %f, currently %f): ", s0, sigma ) ;
checkedFGets ( inputline, sizeof ( inputline ), stdin ) ;
sscanf ( inputline, "%lf", &sigma ) ;
printf ( "Please enter new value for <b> (default %f, currently %f): ", b0, b ) ;
checkedFGets ( inputline, sizeof ( inputline ), stdin ) ;
sscanf ( inputline, "%lf", &b ) ;
printf ( "Please enter new value for <r> (default %f, currently %f): ", r0, r ) ;
checkedFGets ( inputline, sizeof ( inputline ), stdin ) ;
sscanf ( inputline, "%lf", &r ) ;
break ;
case 's' : case 'S' : /* Stop the animation */
animate = 0 ;
break ;
case 'g' : case 'G' : /* Start the animation */
animate = 1 ;
break ;
case ' ' : /* Spacebar: Single step */
animate = 2 ;
break ;
case 27 : /* Escape key */
glutLeaveMainLoop () ;
break ;
}
}
void special_cb ( int key, int x, int y )
{
switch ( key )
{
case GLUT_KEY_UP : /* Rotate up a little */
glRotated ( ROTATION_ANGLE, 0.0, 1.0, 0.0 ) ;
break ;
case GLUT_KEY_DOWN : /* Rotate down a little */
glRotated ( -ROTATION_ANGLE, 0.0, 1.0, 0.0 ) ;
break ;
case GLUT_KEY_LEFT : /* Rotate left a little */
glRotated ( ROTATION_ANGLE, 0.0, 0.0, 1.0 ) ;
break ;
case GLUT_KEY_RIGHT : /* Rotate right a little */
glRotated ( -ROTATION_ANGLE, 0.0, 0.0, 1.0 ) ;
break ;
case GLUT_KEY_PAGE_UP : /* Zoom in a little */
glScaled ( 1.0 / SCALE_FACTOR, 1.0 / SCALE_FACTOR, 1.0 / SCALE_FACTOR ) ;
break ;
case GLUT_KEY_PAGE_DOWN : /* Zoom out a little */
glScaled ( SCALE_FACTOR, SCALE_FACTOR, SCALE_FACTOR ) ;
break ;
}
glutPostRedisplay () ;
}
void mouse_cb ( int button, int updown, int x, int y )
{
if ( updown == GLUT_DOWN )
{
/*double dist = 1.0e20 ; A very large number */
/* The idea here is that we go into "pick" mode and pick the nearest point
to the mouse click position. Unfortunately I don't have the time to implement
it at the moment. */
}
}
void draw_curve ( int index, double position [ NUM_POINTS ][3] )
{
int i = index ;
glBegin ( GL_LINE_STRIP ) ;
do
{
i = ( i == NUM_POINTS-1 ) ? 0 : i + 1 ;
glVertex3dv ( position[i] ) ;
}
while ( i != index ) ;
glEnd () ;
}
void bitmapPrintf (const char *fmt, ...)
{
static char buf[256];
va_list args;
va_start(args, fmt);
#if defined(WIN32) && !defined(__CYGWIN__)
(void) _vsnprintf (buf, sizeof(buf), fmt, args);
#else
(void) vsnprintf (buf, sizeof(buf), fmt, args);
#endif
va_end(args);
glutBitmapString ( GLUT_BITMAP_HELVETICA_12, (unsigned char*)buf ) ;
}
void display_cb ( void )
{
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
glColor3d ( 1.0, 1.0, 1.0 ) ; /* White */
/* Draw some axes */
glBegin ( GL_LINES ) ;
glVertex3d ( 0.0, 0.0, 0.0 ) ;
glVertex3d ( 2.0, 0.0, 0.0 ) ;
glVertex3d ( 0.0, 0.0, 0.0 ) ;
glVertex3d ( 0.0, 1.0, 0.0 ) ;
glVertex3d ( 0.0, 0.0, 0.0 ) ;
glVertex3d ( 0.0, 0.0, 1.0 ) ;
glEnd () ;
glColor3d ( 1.0, 0.0, 0.0 ) ; /* Red */
draw_curve ( array_index, red_position ) ;
glColor3d ( 0.0, 1.0, 0.0 ) ; /* Green */
draw_curve ( array_index, grn_position ) ;
/* Print the distance between the two points */
glColor3d ( 1.0, 1.0, 1.0 ) ; /* White */
glRasterPos2i ( 1, 1 ) ;
bitmapPrintf ( "Distance: %10.6f", distance ) ;
glutSwapBuffers();
}
void reshape_cb ( int width, int height )
{
float ar;
glViewport ( 0, 0, width, height ) ;
glMatrixMode ( GL_PROJECTION ) ;
glLoadIdentity () ;
ar = (float) width / (float) height ;
glFrustum ( -ar, ar, -1.0, 1.0, 10.0, 100.0 ) ;
glMatrixMode ( GL_MODELVIEW ) ;
glLoadIdentity () ;
xcen = 0.0 ;
ycen = 0.0 ;
zcen = 0.0 ;
glTranslated ( xcen, ycen, zcen - 50.0 ) ;
}
void timer_cb ( int value )
{
/* Function called at regular intervals to update the positions of the points */
double deltax, deltay, deltaz ;
int new_index = array_index + 1 ;
/* Set the next timed callback */
glutTimerFunc ( 30, timer_cb, 0 ) ;
if ( animate > 0 )
{
if ( new_index == NUM_POINTS ) new_index = 0 ;
advance_in_time ( time_step, red_position[array_index], red_position[new_index] ) ;
advance_in_time ( time_step, grn_position[array_index], grn_position[new_index] ) ;
array_index = new_index ;
deltax = red_position[array_index][0] - grn_position[array_index][0] ;
deltay = red_position[array_index][1] - grn_position[array_index][1] ;
deltaz = red_position[array_index][2] - grn_position[array_index][2] ;
distance = sqrt ( deltax * deltax + deltay * deltay + deltaz * deltaz ) ;
if ( animate == 2 ) animate = 0 ;
}
glutPostRedisplay () ;
}
/* The Main Program */
int main ( int argc, char *argv[] )
{
int pargc = argc ;
/* Initialize the random number generator */
srand ( 1023 ) ;
/* Set up the OpenGL parameters */
glEnable ( GL_DEPTH_TEST ) ;
glClearColor ( 0.0, 0.0, 0.0, 0.0 ) ;
glClearDepth ( 1.0 ) ;
/* Initialize GLUT */
glutInitWindowSize ( 600, 600 ) ;
glutInit ( &pargc, argv ) ;
glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ) ;
/* Create the window */
glutCreateWindow ( "Lorenz Attractor" ) ;
glutKeyboardFunc ( key_cb ) ;
glutMouseFunc ( mouse_cb ) ;
glutSpecialFunc ( special_cb ) ;
glutDisplayFunc ( display_cb ) ;
glutReshapeFunc ( reshape_cb ) ;
glutTimerFunc ( 30, timer_cb, 0 ) ;
/* Initialize the attractor: The easiest way is to call the keyboard callback with an
* argument of 'r' for Reset.
*/
key_cb ( 'r', 0, 0 ) ;
/* Enter the GLUT main loop */
glutMainLoop () ;
#ifdef _MSC_VER
/* DUMP MEMORY LEAK INFORMATION */
_CrtDumpMemoryLeaks () ;
#endif
return 0 ;
}

BIN
progs/demos/One/objects.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

405
progs/demos/One/one.c Normal file
View File

@ -0,0 +1,405 @@
/*
* one.c
*
* Hey! This was the original file where freeglut development started. Just
* note what I have written here at the time. And see the creation date :)
*
* : This is a wrapper. I still have to figure out
* : how to build shared libraries under *nix :)
*
* Copyright (c) 1999 by Pawel W. Olszta
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Creation date: czw gru 2 11:58:41 CET 1999
*/
#include <stdio.h>
#include <stdlib.h>
#include <GL/freeglut.h>
int g_LeaveGameMode = 0;
int g_InGameMode = 0;
int g_mainwin1, g_mainwin2, g_sw1, g_sw2, g_gamemodewin;
/*
* Call this function to have some text drawn at given coordinates
*/
void PrintText( int nX, int nY, char* pszText )
{
int lines;
char *p;
/*
* Prepare the OpenGL state
*/
glDisable( GL_LIGHTING );
glDisable( GL_DEPTH_TEST );
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
/*
* Have an orthogonal projection matrix set
*/
glOrtho( 0, glutGet( GLUT_WINDOW_WIDTH ),
0, glutGet( GLUT_WINDOW_HEIGHT ),
-1, +1
);
/*
* Now the matrix mode
*/
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
/*
* Now the main text
*/
glColor3ub( 0, 0, 0 );
glRasterPos2i( nX, nY );
for( p=pszText, lines=0; *p; p++ )
{
if( *p == '\n' )
{
lines++;
glRasterPos2i( nX, nY-(lines*18) );
}
glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, *p );
}
/*
* Revert to the old matrix modes
*/
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
/*
* Restore the old OpenGL states
*/
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glEnable( GL_DEPTH_TEST );
glEnable( GL_LIGHTING );
}
/*
* This is the display routine for our sample FreeGLUT windows
*/
void SampleDisplay( void )
{
int win = glutGetWindow();
if (g_InGameMode && win!=g_gamemodewin)
/* Don't draw other windows when in gamemode, those aren't visible
* anyway. Drawing them continuously nonetheless can cause flicker trouble
* on my machine. This only seems to occur only when there are child windows
* among the non-visible windows
*/
return;
if (win==g_sw1)
{
/*
* Clear the screen
*/
glClearColor(0.7f,0.7f,0.7f,1);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glutPostWindowRedisplay(g_mainwin2);
}
else if (win==g_sw2)
{
/*
* Clear the screen
*/
glClearColor(0.3f,0.3f,0.3f,1);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glutPostWindowRedisplay(g_mainwin2);
}
else
{
const GLfloat time = glutGet(GLUT_ELAPSED_TIME) / 1000.f * 40;
/*
* Clear the screen
*/
glClearColor( 0, 0.5, 1, 1 );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
/*
* Have the cube rotated
*/
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glRotatef( time, 0, 0, 1 );
glRotatef( time, 0, 1, 0 );
glRotatef( time, 1, 0, 0 );
/*
* And then drawn...
*/
glColor3f( 1, 1, 0 );
/* glutWireCube( 20.0 ); */
glutWireTeapot( 20.0 );
/* glutWireSphere( 15.0, 15, 15 ); */
/* glColor3f( 0, 1, 0 ); */
/* glutWireCube( 30.0 ); */
/* glutSolidCone( 10, 20, 10, 2 ); */
/*
* Don't forget about the model-view matrix
*/
glPopMatrix( );
/*
* Draw a silly text
*/
if( g_InGameMode == 0 )
PrintText( 20, 20, "Hello there cruel world!" );
else
PrintText( 20, 20, "Press ESC to leave the game mode!" );
}
/*
* And swap this context's buffers
*/
glutSwapBuffers( );
glutPostWindowRedisplay(win);
}
/*
* This is a sample idle function
*/
void SampleIdle( void )
{
if( g_LeaveGameMode == 1 )
{
/* One could do all this just as well in SampleGameModeKeyboard... */
printf("leaving gamemode...\n");
glutLeaveGameMode( );
g_LeaveGameMode = 0;
g_InGameMode = 0;
glutPostWindowRedisplay(g_mainwin1);
glutPostWindowRedisplay(g_mainwin2);
glutPostWindowRedisplay(g_sw1);
glutPostWindowRedisplay(g_sw2);
}
}
void SampleEntry(int state)
{
int window = glutGetWindow () ;
printf ( "Window %d Entry Callback: %d\n", window, state ) ;
}
/*
* The reshape function
*/
void SampleReshape( int nWidth, int nHeight )
{
GLfloat fAspect = (GLfloat) nHeight / (GLfloat) nWidth;
GLfloat fPos[ 4 ] = { 0.0f, 0.0f, 10.0f, 0.0f };
GLfloat fCol[ 4 ] = { 0.5f, 1.0f, 0.0f, 1.0f };
/*
* Update the viewport first
*/
glViewport( 0, 0, nWidth, nHeight );
/*
* Then the projection matrix
*/
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glFrustum( -1.0, 1.0, -fAspect, fAspect, 1.0, 80.0 );
/*
* Move back the camera a bit
*/
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
glTranslatef( 0.0, 0.0, -40.0f );
/*
* Enable some features...
*/
glEnable( GL_CULL_FACE );
glEnable( GL_DEPTH_TEST );
glEnable( GL_NORMALIZE );
/*
* Set up some lighting
*/
glLightfv( GL_LIGHT0, GL_POSITION, fPos );
glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );
/*
* Set up a sample material
*/
glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, fCol );
}
/*
* A sample keyboard callback
*/
void SampleKeyboard( unsigned char cChar, int nMouseX, int nMouseY )
{
printf( "SampleKeyboard(): keypress '%c' at (%i,%i)\n",
cChar, nMouseX, nMouseY );
}
/*
* A sample keyboard callback (for game mode window)
*/
void SampleGameModeKeyboard( unsigned char cChar, int nMouseX, int nMouseY )
{
if( cChar == 27 )
g_LeaveGameMode = 1;
}
/*
* A sample special callback
*/
void SampleSpecial( int nSpecial, int nMouseX, int nMouseY )
{
printf( "SampleSpecial(): special keypress %i at (%i,%i)\n",
nSpecial, nMouseX, nMouseY );
}
/*
* A sample menu callback
*/
void SampleMenu( int menuID )
{
printf( "SampleMenu() callback executed, menuID is %i\n", menuID );
}
/*
* A sample menu status callback
*/
void SampleMenuStatus( int status, int x, int y )
{
printf ( "SampleMenu() callback executed, MenuStatus is %i at (%i,%i)\n", status, x, y );
}
/*
* The sample's entry point
*/
int main( int argc, char** argv )
{
int menuID, subMenuA, subMenuB;
glutInitDisplayString( "stencil~2 rgb double depth>=16 samples" );
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowPosition( 100, 100 );
glutInit( &argc, argv );
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glutMenuStatusFunc( SampleMenuStatus );
glutIdleFunc( SampleIdle );
subMenuA = glutCreateMenu( SampleMenu );
glutAddMenuEntry( "Sub menu A1 (01)", 1 );
glutAddMenuEntry( "Sub menu A2 (02)", 2 );
glutAddMenuEntry( "Sub menu A3 (03)", 3 );
subMenuB = glutCreateMenu( SampleMenu );
glutAddMenuEntry( "Sub menu B1 (04)", 4 );
glutAddMenuEntry( "Sub menu B2 (05)", 5 );
glutAddMenuEntry( "Sub menu B3 (06)", 6 );
glutAddSubMenu( "Going to sub menu A", subMenuA );
menuID = glutCreateMenu( SampleMenu );
glutAddMenuEntry( "Entry one", 1 );
glutAddMenuEntry( "Entry two", 2 );
glutAddMenuEntry( "Entry three", 3 );
glutAddMenuEntry( "Entry four", 4 );
glutAddMenuEntry( "Entry five", 5 );
glutAddSubMenu( "Enter sub menu A", subMenuA );
glutAddSubMenu( "Enter sub menu B", subMenuB );
g_mainwin1 = glutCreateWindow( "Hello world!" );
glutDisplayFunc( SampleDisplay );
glutReshapeFunc( SampleReshape );
glutKeyboardFunc( SampleKeyboard );
glutSpecialFunc( SampleSpecial );
glutEntryFunc( SampleEntry );
glutAttachMenu( GLUT_LEFT_BUTTON );
glutInitWindowPosition( 200, 200 );
g_mainwin2 = glutCreateWindow( "I am not Jan B." );
glutDisplayFunc( SampleDisplay );
glutReshapeFunc( SampleReshape );
glutKeyboardFunc( SampleKeyboard );
glutSpecialFunc( SampleSpecial );
glutEntryFunc( SampleEntry );
glutAttachMenu( GLUT_LEFT_BUTTON );
glutSetMenu(subMenuA);
glutAttachMenu( GLUT_RIGHT_BUTTON );
g_sw1=glutCreateSubWindow(g_mainwin2,200,0,100,100);
glutDisplayFunc( SampleDisplay );
glutSetMenu(subMenuB);
glutAttachMenu( GLUT_LEFT_BUTTON );
g_sw2=glutCreateSubWindow(g_sw1,50,0,50,50);
glutDisplayFunc( SampleDisplay );
glutSetMenu(menuID);
glutAttachMenu( GLUT_RIGHT_BUTTON );
printf( "Testing game mode string parsing, don't panic!\n" );
glutGameModeString( "320x240:32@100" );
glutGameModeString( "640x480:16@72" );
glutGameModeString( "1024x768" );
glutGameModeString( ":32@120" );
glutGameModeString( "Toudi glupcze, Danwin bedzie moj!" );
glutGameModeString( "640x480:37@300" ); /* this one should fail */
glutEnterGameMode();
glutGameModeString( "800x600" ); /* this one is likely to succeed */
g_gamemodewin = glutEnterGameMode();
if (glutGameModeGet(GLUT_GAME_MODE_ACTIVE))
g_InGameMode = 1;
glutDisplayFunc( SampleDisplay );
glutReshapeFunc( SampleReshape );
glutKeyboardFunc( SampleGameModeKeyboard );
glutEntryFunc( SampleEntry );
glutSetMenu(menuID);
glutAttachMenu( GLUT_LEFT_BUTTON );
printf( "current window is %ix%i at (%i,%i)\n",
glutGet( GLUT_WINDOW_WIDTH ), glutGet( GLUT_WINDOW_HEIGHT ),
glutGet( GLUT_WINDOW_X ), glutGet( GLUT_WINDOW_Y )
);
/*
* Describe pixel format
*/
printf("The current window has %i red bits, %i green bits, %i blue bits and %i alpha bits for a total buffer size of %i bits\n",glutGet(GLUT_WINDOW_RED_SIZE),glutGet(GLUT_WINDOW_GREEN_SIZE),glutGet(GLUT_WINDOW_BLUE_SIZE),glutGet(GLUT_WINDOW_ALPHA_SIZE),glutGet(GLUT_WINDOW_BUFFER_SIZE));
printf("It furthermore has %i depth bits and %i stencil bits\n",glutGet(GLUT_WINDOW_DEPTH_SIZE),glutGet(GLUT_WINDOW_STENCIL_SIZE));
/*
* Enter the main FreeGLUT processing loop
*/
glutMainLoop();
/*
* returned from mainloop after window closed
* see glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_GLUTMAINLOOP_RETURNS); above
*/
printf( "glutMainLoop() termination works fine!\n" );
return EXIT_SUCCESS;
}
/*** END OF FILE ***/

1
progs/demos/One/one.rc Normal file
View File

@ -0,0 +1 @@
GLUT_ICON ICON DISCARDABLE "objects.ico"

View File

@ -0,0 +1,175 @@
/* Indexed color mode demo
* Written by John Tsiombikas <nuclear@member.fsf.org>
*
* Demonstrates how to create an indexed color OpenGL context, manipulate the
* colormap, and do lighting in indexed color mode.
*
* Obviously none of this will work if your OpenGL implementation and/or
* window system does not support indexed color.
*/
#include <stdio.h>
#include <stdlib.h>
#include <GL/freeglut.h>
void display(void);
void reshape(int x, int y);
void keyb(unsigned char key, int x, int y);
void mouse(int bn, int st, int x, int y);
void motion(int x, int y);
float cam_theta, cam_phi, cam_dist = 6;
int prev_x, prev_y;
int bnstate[8];
int sphere, torus;
int redramp[3], blueramp[3];
int main(int argc, char **argv)
{
int i, ncolors, rampsz, maxdif;
float x;
glutInit(&argc, argv);
/* request an indexed color visual, this will fail on most modern systems */
glutInitDisplayMode(GLUT_INDEX | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(640, 480);
glutCreateWindow("FreeGLUT indexed color demo");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyb);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
ncolors = glutGet(GLUT_WINDOW_COLORMAP_SIZE);
printf("Colormap size: %d\n", ncolors);
rampsz = ncolors / 2;
maxdif = (int)(rampsz * 0.75f);
/* prepare a palette with two color ramps for a red and a blue object */
for(i=0; i<rampsz; i++) {
if(i < maxdif) {
x = (float)i / (maxdif - 1);
glutSetColor(i, x, 0, 0);
glutSetColor(i + rampsz, 0, 0, x);
} else {
x = (float)(i - maxdif) / (rampsz - maxdif - 1);
glutSetColor(i, 1, x, x);
glutSetColor(i + rampsz, x, x, 1);
}
}
/* prepare the indexed color lighting descriptors needed by OpenGL to
* compute lighting in indexed color mode.
*/
redramp[0] = 0; /* unlit color index*/
redramp[1] = maxdif - 1; /* maximum diffuse color index*/
redramp[2] = rampsz - 1; /* maximum specularity color index */
blueramp[0] = rampsz; /* ... and same for the blue ramp ... */
blueramp[1] = rampsz + maxdif - 1;
blueramp[2] = rampsz * 2 - 1;
/* set the specular exponent for all objects once */
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 40);
sphere = glGenLists(1);
glNewList(sphere, GL_COMPILE);
glutSolidSphere(1, 30, 15);
glEndList();
torus = glGenLists(1);
glNewList(torus, GL_COMPILE);
glutSolidTorus(0.35, 0.9, 20, 40);
glEndList();
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glutMainLoop();
return 0;
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -cam_dist);
glRotatef(cam_phi, 1, 0, 0);
glRotatef(cam_theta, 0, 1, 0);
/* set up the red object's lighting indices */
glMaterialiv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, redramp);
glPushMatrix();
glTranslatef(-1.5, 0, 0);
glCallList(sphere);
glPopMatrix();
/* setup the blue object's lighting indices */
glMaterialiv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES, blueramp);
glPushMatrix();
glTranslatef(1.5, 0, 0);
glRotatef(90, 1, 0, 0);
glCallList(torus);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int x, int y)
{
glViewport(0, 0, x, y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50.0, (float)x / y, 0.5, 500.0);
}
void keyb(unsigned char key, int x, int y)
{
switch(key) {
case 27:
exit(0);
}
}
void mouse(int bn, int st, int x, int y)
{
bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN;
prev_x = x;
prev_y = y;
}
void motion(int x, int y)
{
int dx, dy;
dx = x - prev_x;
dy = y - prev_y;
prev_x = x;
prev_y = y;
if(!(dx | dy)) return;
if(bnstate[0]) {
cam_theta += dx * 0.5f;
cam_phi += dy * 0.5f;
if(cam_phi < -90) cam_phi = -90;
if(cam_phi > 90) cam_phi = 90;
glutPostRedisplay();
}
if(bnstate[2]) {
cam_dist += dy * 0.1f;
if(cam_dist < 0) cam_dist = 0;
glutPostRedisplay();
}
}

View File

@ -0,0 +1,58 @@
/*
* ------------------------------------------
* user_error_handler.c
*
* This is a sample program showing a basic
* user defined error handlers with FreeGLUT
* ------------------------------------------
*/
#include <GL/freeglut.h>
/*
* ------------------------------------------
* Declare our own Error handler for FreeGLUT
* ------------------------------------------
*/
/* This declares the vprintf() routine */
#include <stdio.h>
/* This declares the va_list type */
#include <stdarg.h>
/* The new handler looks like a vprintf prototype */
void myError (const char *fmt, va_list ap)
{
fprintf(stderr, "myError: Entering user defined error handler\n");
/* print warning message */
fprintf(stderr, "myError:");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
/* deInitialize the freeglut state */
fprintf(stderr, "myError: Calling glutExit()\n");
glutExit();
/* terminate error handler appropriately */
fprintf(stderr, "myError: Exit-ing handler routine\n");
exit(1);
}
/*
* ------------------------------------------
* Just enough code to create the error to
* demonstrate the user defined handler
* ------------------------------------------
*/
int main(int argc, char** argv)
{
glutInitErrorFunc(&myError);
glutCreateWindow ("error test"); /* This is an error! */
glutInit(&argc, argv); /* Should be called
after glutInit() */
glutMainLoop();
return 0;
}

View File

@ -0,0 +1,221 @@
/* Joystick demo
* Written by John Tsiombikas <nuclear@member.fsf.org>
* Press escape or q to exit.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <math.h>
#include <GL/freeglut.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifdef _MSC_VER
#pragma warning (disable: 4305 4244)
#endif
void display(void);
void rect(float x0, float y0, float x1, float y1);
void text(float x, float y, const char *fmt, ...);
void widget(float xsz, float ysz, float xpos, float ypos);
void button(float sz, float state);
void reshape(int x, int y);
void keyboard(unsigned char key, int x, int y);
void joystick(unsigned int bmask, int x, int y, int z);
int win_width, win_height;
int joy[3];
unsigned int joy_bmask;
int num_buttons, bhist;
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(800, 600);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("Joystick demo");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutJoystickFunc(joystick, 25);
if(!glutGet(GLUT_HAS_JOYSTICK)) {
fprintf(stderr, "no joystick detected\n");
return 1;
}
printf("Joystick axes: %d\n", glutGet(GLUT_JOYSTICK_AXES));
num_buttons = glutGet(GLUT_JOYSTICK_BUTTONS);
printf("Joystick buttons: %d\n", num_buttons);
glutMainLoop();
}
#define WSZ 0.8
#define RAD (WSZ / 8)
#define FRM 0.0075
#define MAX_BSZ (WSZ / 9)
void display(void)
{
float dmax = WSZ * 0.5f - RAD;
float jx, jy, jz, cury, bsz;
int i, num;
jx = joy[0] / 1000.0f;
jy = joy[1] / 1000.0f;
jz = joy[2] / 1000.0f;
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(-WSZ / 2, 0, 0);
widget(WSZ, WSZ, jx * dmax, -jy * dmax);
glPopMatrix();
glPushMatrix();
glTranslatef(WSZ / 2, 0, 0);
widget(RAD * 2, WSZ, 0, -jz * dmax);
glPopMatrix();
if(num_buttons > 0) {
num = num_buttons;
} else {
bhist |= joy_bmask;
num = 0;
while(num < 32 && bhist >> num) {
num++;
}
}
if(num) {
if(num > 32) num = 32;
bsz = 2.0 / (num * 1.4);
if(bsz > MAX_BSZ) bsz = MAX_BSZ;
glPushMatrix();
glTranslatef(-bsz * 1.4 * (num - 1) / 2, 0.7, 0);
for(i=0; i<num; i++) {
button(bsz, joy_bmask & (1 << i));
glTranslatef(bsz * 1.4, 0, 0);
}
glPopMatrix();
}
glColor3f(0, 1, 0);
cury = -2 * WSZ / 3;
text(-WSZ * 0.75, cury, "X: %d", joy[0]);
cury -= 0.08;
text(-WSZ * 0.75, cury, "Y: %d", joy[1]);
cury -= 0.08;
text(-WSZ * 0.75, cury, "Z: %d", joy[2]);
glutSwapBuffers();
}
void rect(float x0, float y0, float x1, float y1)
{
glVertex2f(x0, y0);
glVertex2f(x1, y0);
glVertex2f(x1, y1);
glVertex2f(x0, y1);
}
void text(float x, float y, const char *fmt, ...)
{
va_list ap;
char buf[256], *s;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glRasterPos2f(x, y);
s = buf;
while(*s) {
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, *s++);
}
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void widget(float xsz, float ysz, float xpos, float ypos)
{
int i;
float x, y, theta;
glBegin(GL_QUADS);
glColor3f(1, 1, 1);
rect(-xsz / 2 - FRM, -ysz / 2 - FRM, xsz / 2 + FRM, ysz / 2 + FRM);
glColor3f(0.1, 0.1, 0.1);
rect(-xsz / 2, -ysz / 2, xsz / 2, ysz / 2);
glEnd();
glBegin(GL_TRIANGLE_FAN);
glColor3f(1, 0, 0);
glVertex2f(xpos, ypos);
for(i=0; i<20; i++) {
theta = M_PI * 2 * i / 19.0;
x = cos(theta) * RAD;
y = sin(theta) * RAD;
glVertex2f(xpos + x, ypos + y);
}
glEnd();
}
void button(float sz, float state)
{
glBegin(GL_QUADS);
glColor3f(1, 1, 1);
rect(-sz / 2 - FRM, -sz / 2 - FRM, sz / 2 + FRM, sz / 2 + FRM);
glColor3f(state ? 1 : 0.2, 0.2, 0.2);
rect(-sz / 2, -sz / 2, sz / 2, sz / 2);
glEnd();
}
void reshape(int x, int y)
{
float aspect = (float)x / y;
win_width = x;
win_height = y;
glViewport(0, 0, x, y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(1.0 / aspect, 1, 1);
}
void keyboard(unsigned char key, int x, int y)
{
if(key == 27 || key == 'q') {
exit(0);
}
}
void joystick(unsigned int bmask, int x, int y, int z)
{
joy[0] = x;
joy[1] = y;
joy[2] = z;
joy_bmask = bmask;
glutPostRedisplay();
}

View File

@ -0,0 +1,156 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <GL/freeglut.h>
void display(void);
void draw_text(int x, int y, const char *str);
const char *skeyname(int skey);
void reshape(int x, int y);
void keypress(unsigned char key, int x, int y);
void keyrelease(unsigned char key, int x, int y);
void skeypress(int key, int x, int y);
void skeyrelease(int key, int x, int y);
unsigned int modstate;
int cur_key = -1;
int cur_skey = -1;
int win_width, win_height;
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(400, 200);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("Keyboard demo");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keypress);
glutKeyboardUpFunc(keyrelease);
glutSpecialFunc(skeypress);
glutSpecialUpFunc(skeyrelease);
glutMainLoop();
return 0;
}
void display(void)
{
char str[256];
glClear(GL_COLOR_BUFFER_BIT);
strcpy(str, "Key:");
if(cur_key > 0) {
if(isprint(cur_key)) {
sprintf(str + 4, " '%c'", cur_key);
} else {
sprintf(str + 4, " 0x%02x", cur_key);
}
if(modstate & GLUT_ACTIVE_SHIFT) {
strcat(str, " shift");
}
if(modstate & GLUT_ACTIVE_CTRL) {
strcat(str, " ctrl");
}
if(modstate & GLUT_ACTIVE_ALT) {
strcat(str, " alt");
}
if(modstate & GLUT_ACTIVE_SUPER) {
strcat(str, " super");
}
}
draw_text(win_width / 3, 2 * win_height / 3, str);
strcpy(str, "Special key: ");
if(cur_skey > 0) {
strcat(str, skeyname(cur_skey));
}
draw_text(win_width / 3, win_height / 3, str);
glutSwapBuffers();
}
void draw_text(int x, int y, const char *str)
{
glRasterPos2i(x, y);
while(*str) {
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *str++);
}
}
const char *skeyname(int skey)
{
static const char *fkeys[] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"};
switch(skey) {
case GLUT_KEY_LEFT: return "left";
case GLUT_KEY_UP: return "up";
case GLUT_KEY_RIGHT: return "right";
case GLUT_KEY_DOWN: return "down";
case GLUT_KEY_PAGE_UP: return "page up";
case GLUT_KEY_PAGE_DOWN: return "page down";
case GLUT_KEY_HOME: return "home";
case GLUT_KEY_END: return "end";
case GLUT_KEY_INSERT: return "insert";
case GLUT_KEY_NUM_LOCK: return "num lock";
case GLUT_KEY_BEGIN: return "begin";
case GLUT_KEY_DELETE: return "delete";
case GLUT_KEY_SHIFT_L: return "L Shift";
case GLUT_KEY_SHIFT_R: return "R Shift";
case GLUT_KEY_CTRL_L: return "L Ctrl";
case GLUT_KEY_CTRL_R: return "R Ctrl";
case GLUT_KEY_ALT_L: return "L Alt";
case GLUT_KEY_ALT_R: return "R Alt";
case GLUT_KEY_SUPER_L: return "L Super";
case GLUT_KEY_SUPER_R: return "R Super";
default:
if(skey >= GLUT_KEY_F1 && skey <= GLUT_KEY_F12) {
return fkeys[skey - GLUT_KEY_F1];
}
break;
}
return "<unknown>";
}
void reshape(int x, int y)
{
win_width = x;
win_height = y;
glViewport(0, 0, x, y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, x, 0, y, -1, 1);
}
void keypress(unsigned char key, int x, int y)
{
if(key == 27) exit(0);
modstate = glutGetModifiers();
cur_key = key;
glutPostRedisplay();
}
void keyrelease(unsigned char key, int x, int y)
{
cur_key = -1;
glutPostRedisplay();
}
void skeypress(int key, int x, int y)
{
cur_skey = key;
glutPostRedisplay();
}
void skeyrelease(int key, int x, int y)
{
cur_skey = -1;
glutPostRedisplay();
}

View File

@ -0,0 +1,163 @@
/**
* Sample multi-touch program that displays a square where a cursor
* clicks, with a different color for each cursor.
*
* Copyright (C) 2012 Sylvain Beucler
*
* 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/freeglut.h>
#include <GL/gl.h>
#define NUM_DEVICES 16
#define NUM_CURSORS 64
typedef struct cursor {
char on;
float x;
float y;
} *Cursor;
struct cursor cursors[NUM_DEVICES][NUM_CURSORS];
static float square[] = {
-.5, -.5,
.5, -.5,
-.5, .5,
.5, .5,
};
void onDisplay(void) {
int d;
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, square);
for (d = 0; d < NUM_DEVICES; d++) {
int c;
for (c = 0; c < NUM_CURSORS; c++) {
Cursor C = &cursors[d][c];
if (C->on) {
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(C->x, C->y, 0);
glScalef(30, 30, 1);
switch(c) {
case 0:
glColor4f(0,0,1,1);
break;
case 1:
glColor4f(0,1,0,1);
break;
case 2:
glColor4f(1,0,0,1);
break;
case 3:
glColor4f(1,1,1,1);
break;
default:
glColor4d(.5,.5,.5,1);
break;
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
}
}
glDisableClientState(GL_VERTEX_ARRAY);
glutSwapBuffers();
}
void onMouse(int button, int state, int x, int y) {
if (button == 0) {
cursors[0][0].on = (state == GLUT_DOWN);
cursors[0][0].x = (float)x;
cursors[0][0].y = (float)y;
printf("normal click\n");
}
}
void onMotion(int x, int y) {
cursors[0][0].x = (float)x;
cursors[0][0].y = (float)y;
}
/* Using FG2.8 (reversed) prototype for now */
/* void onMultiButton(int cursor_id, int button, int state, int x, int y) { */
void onMultiButton(int cursor_id, int x, int y, int button, int state) {
if (cursor_id >= NUM_CURSORS) {
fprintf(stderr, "cursor_id (%d) >= NUM_CURSORS (%d), out of slots\n", cursor_id, NUM_CURSORS);
return;
}
if (button == 0) {
cursors[0][cursor_id].on = (state == GLUT_DOWN);
cursors[0][cursor_id].x = (float)x;
cursors[0][cursor_id].y = (float)y;
printf("multi-touch %d click\n", cursor_id);
}
}
void onMultiMotion(int cursor_id, int x, int y) {
if (cursor_id >= NUM_CURSORS) {
fprintf(stderr, "cursor_id (%d) >= NUM_CURSORS (%d), out of slots\n", cursor_id, NUM_CURSORS);
return;
}
cursors[0][cursor_id].x = (float)x;
cursors[0][cursor_id].y = (float)y;
}
void onReshape(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glOrtho(0, width, height, 0, -1, 1);
}
void onIdle(void) {
glutPostRedisplay();
}
int main(int argc, char* argv[]) {
memset(cursors, 0, sizeof(cursors));
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
glutInitWindowSize(640, 480);
glutCreateWindow("Multi-touch test");
glutDisplayFunc(onDisplay);
glutReshapeFunc(onReshape);
glutIdleFunc(onIdle);
glutMouseFunc(onMouse);
glutMotionFunc(onMotion);
glutMultiButtonFunc(onMultiButton);
glutMultiMotionFunc(onMultiMotion);
glutMainLoop();
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,395 @@
#include <stdio.h>
#include <GL/freeglut.h>
int nWindow, nChildWindow = -1;
int nLoopMain = 0;
GLboolean bChildPosDone = GL_FALSE, bChildSizeDone = GL_FALSE;
void SampleKeyboard( unsigned char cChar, int nMouseX, int nMouseY );
void Redisplay();
void Reshape(int width, int height);
void Position(int x, int y);
void WindowStatus(int state);
void DrawQuad()
{
int width = glutGet(GLUT_WINDOW_WIDTH);
int height = glutGet(GLUT_WINDOW_HEIGHT);
glBegin(GL_QUADS);
glVertex2d(width*.25, height*.75);
glVertex2d(width*.75, height*.75);
glVertex2d(width*.75, height*.25);
glVertex2d(width*.25, height*.25);
glEnd();
}
void UnhideTimer(int window)
{
glutSetWindow(window);
glutShowWindow();
}
void ChangeTitleTimer(int unused)
{
glutSetIconTitle("new icon title");
glutSetWindowTitle("new test title");
}
void SampleKeyboard( unsigned char cChar, int nMouseX, int nMouseY )
{
switch (cChar)
{
case 27:
glutLeaveMainLoop();
break;
case 'f':
case 'F':
printf("main window toggle fullscreen\n");
glutFullScreenToggle();
break;
case 'r':
case 'R':
if (nChildWindow!=-1 && cChar=='r') /* Capital R always resizes the main window*/
{
glutSetWindow(nChildWindow);
printf("child window resize\n");
if (!bChildSizeDone)
glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)+50,glutGet(GLUT_WINDOW_HEIGHT)+50);
else
glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)-50,glutGet(GLUT_WINDOW_HEIGHT)-50);
bChildSizeDone = !bChildSizeDone;
}
else
{
glutSetWindow(nWindow);
printf("main window resize\n");
if (glutGet(GLUT_WINDOW_WIDTH)<400)
glutReshapeWindow(600,300);
else
glutReshapeWindow(300,300);
}
break;
case 'm':
case 'M':
if (nChildWindow!=-1 && cChar=='m') /* Capital M always moves the main window*/
{
glutSetWindow(nChildWindow);
/* The window position you request is relative to the top-left
* corner of the client area of the parent window.
*/
if (!bChildPosDone)
glutPositionWindow(glutGet(GLUT_WINDOW_X)+50,glutGet(GLUT_WINDOW_Y)+50);
else
glutPositionWindow(glutGet(GLUT_WINDOW_X)-50,glutGet(GLUT_WINDOW_Y)-50);
bChildPosDone = !bChildPosDone;
}
else
{
glutSetWindow(nWindow);
printf("main window position\n");
/* The window position you request is the outer top-left of the window,
* the client area is at a different position if the window has borders
* and/or a title bar.
*/
if (glutGet(GLUT_WINDOW_X)<400)
glutPositionWindow(600,300);
else
glutPositionWindow(300,300);
}
break;
case 'd':
case 'D':
if (nChildWindow!=-1 && cChar=='d') /* Capital D always moves+resizes the main window*/
{
glutSetWindow(nChildWindow);
if (!bChildPosDone)
glutPositionWindow(glutGet(GLUT_WINDOW_X)+50,glutGet(GLUT_WINDOW_Y)+50);
else
glutPositionWindow(glutGet(GLUT_WINDOW_X)-50,glutGet(GLUT_WINDOW_Y)-50);
bChildPosDone = !bChildPosDone;
if (!bChildSizeDone)
glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)+50,glutGet(GLUT_WINDOW_HEIGHT)+50);
else
glutReshapeWindow(glutGet(GLUT_WINDOW_WIDTH)-50,glutGet(GLUT_WINDOW_HEIGHT)-50);
bChildSizeDone = !bChildSizeDone;
}
else
{
if (glutGet(GLUT_WINDOW_X)<400)
glutPositionWindow(600,300);
else
glutPositionWindow(300,300);
if (glutGet(GLUT_WINDOW_WIDTH)<400)
glutReshapeWindow(600,300);
else
glutReshapeWindow(300,300);
}
break;
case 'c':
case 'C':
if (nChildWindow==-1)
{
int width = glutGet(GLUT_WINDOW_WIDTH);
int height = glutGet(GLUT_WINDOW_HEIGHT);
/* open child window */
printf("open child window\n");
nChildWindow = glutCreateSubWindow(nWindow,(int)(width*.35),(int)(height*.35),(int)(width*.3),(int)(height*.3));
glutKeyboardFunc( SampleKeyboard );
glutDisplayFunc( Redisplay );
glutReshapeFunc( Reshape );
glutPositionFunc( Position );
glutWindowStatusFunc( WindowStatus );
}
else
{
/* close child window */
printf("close child window\n");
glutSetWindow(nWindow);
glutDestroyWindow(nChildWindow);
nChildWindow = -1;
bChildSizeDone = GL_FALSE;
bChildPosDone = GL_FALSE;
}
break;
case 'i':
case 'I':
glutIconifyWindow();
glutTimerFunc(1500, ChangeTitleTimer, 0);
break;
case 'h':
case 'H':
if (nChildWindow!=-1 && cChar=='h') /* Capital H always hides the main window*/
{
glutSetWindow(nChildWindow);
glutTimerFunc(2000, UnhideTimer, nChildWindow);
}
else
{
glutSetWindow(nWindow);
glutTimerFunc(2000, UnhideTimer, nWindow);
}
glutHideWindow();
break;
case 'p':
case 'P':
if (nChildWindow!=-1 && cChar=='p') /* Capital P always changes pointer for the main window*/
{
glutSetWindow(nChildWindow);
if (glutGet(GLUT_WINDOW_CURSOR)==GLUT_CURSOR_TOP_SIDE)
{
glutSetCursor(GLUT_CURSOR_RIGHT_ARROW);
printf("reverting child window cursor\n");
}
else
{
glutSetCursor(GLUT_CURSOR_TOP_SIDE);
printf("changing child window cursor\n");
}
}
else
{
glutSetWindow(nWindow);
if (glutGet(GLUT_WINDOW_CURSOR)==GLUT_CURSOR_CYCLE)
{
glutSetCursor(GLUT_CURSOR_RIGHT_ARROW);
printf("reverting main window cursor\n");
}
else
{
glutSetCursor(GLUT_CURSOR_CYCLE);
printf("changing main window cursor\n");
}
}
break;
default:
break;
}
}
void Idle(void)
{
glutPostRedisplay();
}
void Reshape(int width, int height)
{
int win = glutGetWindow();
printf("reshape %s, client area: %dx%d\n",win==nWindow?"main":"child",
width, height);
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,width,0,height);
if (win==nWindow && nChildWindow!=-1)
{
/* Put child window in right place */
int x = (int)(width*.35), y=(int)(height*.35), w=(int)(width*.3), h = (int)(height*.3);
if (bChildPosDone)
{
x += 50;
y += 50;
}
if (bChildSizeDone)
{
w += 50;
h += 50;
}
glutSetWindow(nChildWindow);
glutPositionWindow(x,y);
glutReshapeWindow(w,h);
glutSetWindow(nWindow);
}
}
void Position(int x, int y)
{
int win = glutGetWindow();
printf("position, %s: (%d,%d)\n",win==nWindow?"top-left (non-client) of main":"top-left of child relative to parent",
x, y);
}
void WindowStatus(int state)
{
int win = glutGetWindow();
printf("windowstatus (win %i): %i\n",win,state);
}
void Redisplay(void)
{
int win = glutGetWindow();
int viewport[4];
if (win==nWindow)
{
glClearColor(.2f,0.f,0.f,0.f);
glColor3f(1,1,1);
}
else
{
/* child window */
glClearColor(.0f,.2f,0.f,0.f);
glColor3f(.5,.5,.5);
glutPostWindowRedisplay(nWindow);
}
glClear(GL_COLOR_BUFFER_BIT);
DrawQuad();
if (win==nWindow)
{
glColor3f(1, 1, 0);
glGetIntegerv(GL_VIEWPORT, viewport);
glRasterPos2i(2, -glutBitmapHeight(GLUT_BITMAP_9_BY_15)+3+viewport[3]);
glutBitmapString(GLUT_BITMAP_9_BY_15, (unsigned char*)"press f/r/m/d/c/i/h/p");
}
glutSwapBuffers();
glutPostWindowRedisplay(win);
}
void Timer(int unused)
{
int win = glutGetWindow();
int x, y;
int width, height;
int border, caption;
x = glutGet(GLUT_WINDOW_X);
y = glutGet(GLUT_WINDOW_Y);
width = glutGet(GLUT_WINDOW_WIDTH);
height = glutGet(GLUT_WINDOW_HEIGHT);
border = glutGet(GLUT_WINDOW_BORDER_WIDTH);
caption = glutGet(GLUT_WINDOW_HEADER_HEIGHT);
/* returned position is top-left of client area, to get top-left of
* of window you'll need to add the size of the border and caption
* of the current window (can be 0).
* Note that the window position is not necessarily positive (e.g.
* when the window is on a monitor to the left of the primary monitor
* or simply when maximized--try pressing the maximize button).
* the returned size is the size of the client area
* Note that the top-left of a child window is relative to the
* top-left of the client area of the parent.
*/
/* printf("window border: %dpx, caption: %dpx\n",border,caption); */
if (win==nWindow)
printf("main window %dx%d, top-left of client at: (%d,%d), of window at: (%d,%d)\n",
width, height,
x ,y,
x-border,
y-caption);
else
printf("child window %dx%d, top-left of client at: (%d,%d), relative to parent\n",
width, height,
x ,y);
/* (re)set the timer callback and ask glut to call it in 500 ms */
glutTimerFunc(500, Timer, 0);
}
int main(int argc, char* argv[])
{
int border, caption;
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE /*| GLUT_BORDERLESS*/); /* do try as well with GLUT_BORDERLESS and GLUT_CAPTIONLESS */
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_GLUTMAINLOOP_RETURNS);
/* Get border and caption size of default window style */
border = glutGet(GLUT_WINDOW_BORDER_WIDTH);
caption = glutGet(GLUT_WINDOW_HEADER_HEIGHT);
printf("default window style border: %dpx, caption: %dpx\n",border,caption);
/* NB: The window position you request is the outer top-left of the
* window, the client area is at a different position if the window has
* borders and/or a title bar.
*/
glutInitWindowPosition(150,250);
glutInitWindowSize(200,200);
nWindow = glutCreateWindow("test");
glutSetIconTitle("test icon title");
printf("main window id: %d\n", nWindow);
glutKeyboardFunc( SampleKeyboard );
glutDisplayFunc( Redisplay );
glutReshapeFunc( Reshape );
glutPositionFunc( Position );
glutWindowStatusFunc( WindowStatus );
glutTimerFunc(300, Timer, 0);
glutMainLoop();
printf("glutMainLoop returned\n");
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,219 @@
#include <string.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include "glmatrix.h"
#ifndef M_PI
#define M_PI 3.141592653589793
#endif
#define MMODE_IDX(x) ((x) - GL_MODELVIEW)
#define MAT_STACK_SIZE 32
#define MAT_IDENT {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}
static int mm_idx = 0;
static float mat_stack[3][MAT_STACK_SIZE][16] = {{MAT_IDENT}, {MAT_IDENT}, {MAT_IDENT}};
static int stack_top[3];
void gl_matrix_mode(int mm)
{
mm_idx = MMODE_IDX(mm);
}
void gl_push_matrix(void)
{
int top = stack_top[mm_idx];
memcpy(mat_stack[mm_idx][top + 1], mat_stack[mm_idx][top], 16 * sizeof(float));
stack_top[mm_idx]++;
}
void gl_pop_matrix(void)
{
stack_top[mm_idx]--;
}
void gl_load_identity(void)
{
static const float idmat[] = MAT_IDENT;
int top = stack_top[mm_idx];
float *mat = mat_stack[mm_idx][top];
memcpy(mat, idmat, sizeof idmat);
}
void gl_load_matrixf(const float *m)
{
int top = stack_top[mm_idx];
float *mat = mat_stack[mm_idx][top];
memcpy(mat, m, 16 * sizeof *mat);
}
#define M4(i, j) ((i << 2) + j)
void gl_mult_matrixf(const float *m2)
{
int i, j;
int top = stack_top[mm_idx];
float *m1 = mat_stack[mm_idx][top];
float res[16];
for(i=0; i<4; i++) {
for(j=0; j<4; j++) {
res[M4(i,j)] = m1[M4(i,0)] * m2[M4(0,j)] +
m1[M4(i,1)] * m2[M4(1,j)] +
m1[M4(i,2)] * m2[M4(2,j)] +
m1[M4(i,3)] * m2[M4(3,j)];
}
}
memcpy(m1, res, sizeof res);
}
void gl_translatef(float x, float y, float z)
{
float mat[] = MAT_IDENT;
mat[12] = x;
mat[13] = y;
mat[14] = z;
gl_mult_matrixf(mat);
}
void gl_rotatef(float angle, float x, float y, float z)
{
float mat[] = MAT_IDENT;
float angle_rad = (float)M_PI * angle / 180.f;
float sina = (float)sin(angle_rad);
float cosa = (float)cos(angle_rad);
float one_minus_cosa = 1.f - cosa;
float nxsq = x * x;
float nysq = y * y;
float nzsq = z * z;
mat[0] = nxsq + (1.f - nxsq) * cosa;
mat[4] = x * y * one_minus_cosa - z * sina;
mat[8] = x * z * one_minus_cosa + y * sina;
mat[1] = x * y * one_minus_cosa + z * sina;
mat[5] = nysq + (1.f - nysq) * cosa;
mat[9] = y * z * one_minus_cosa - x * sina;
mat[2] = x * z * one_minus_cosa - y * sina;
mat[6] = y * z * one_minus_cosa + x * sina;
mat[10] = nzsq + (1.f - nzsq) * cosa;
gl_mult_matrixf(mat);
}
void gl_scalef(float x, float y, float z)
{
float mat[] = MAT_IDENT;
mat[0] = x;
mat[5] = y;
mat[10] = z;
gl_mult_matrixf(mat);
}
void gl_ortho(float left, float right, float bottom, float top, float znear, float zfar)
{
float mat[] = MAT_IDENT;
float dx = right - left;
float dy = top - bottom;
float dz = zfar - znear;
float tx = -(right + left) / dx;
float ty = -(top + bottom) / dy;
float tz = -(zfar + znear) / dz;
float sx = 2.f / dx;
float sy = 2.f / dy;
float sz = -2.f / dz;
mat[0] = sx;
mat[5] = sy;
mat[10] = sz;
mat[12] = tx;
mat[13] = ty;
mat[14] = tz;
gl_mult_matrixf(mat);
}
void gl_frustum(float left, float right, float bottom, float top, float znear, float zfar)
{
float mat[] = MAT_IDENT;
float dx = right - left;
float dy = top - bottom;
float dz = zfar - znear;
float a = (right + left) / dx;
float b = (top + bottom) / dy;
float c = -(zfar + znear) / dz;
float d = -2.f * zfar * znear / dz;
mat[0] = 2.f * znear / dx;
mat[5] = 2.f * znear / dy;
mat[8] = a;
mat[9] = b;
mat[10] = c;
mat[11] = -1.f;
mat[14] = d;
mat[15] = 0;
gl_mult_matrixf(mat);
}
void glu_perspective(float vfov, float aspect, float znear, float zfar)
{
float vfov_rad = (float)M_PI * vfov / 180.f;
float x = znear * (float)tan(vfov_rad / 2.f);
gl_frustum(-aspect * x, aspect * x, -x, x, znear, zfar);
}
/* return the matrix (16 elements, 4x4 matrix, row-major order */
float* get_matrix(int mm)
{
int idx = MMODE_IDX(mm);
int top = stack_top[idx];
return mat_stack[idx][top];
}
#define M3(i, j) ((i * 3) + j)
static float inv_transpose_result[9];
/* return the inverse transpose of the left-upper 3x3 of a matrix
The returned pointer is only valid until the next time this function is
called, so make a deep copy when you want to keep it around.
*/
float* get_inv_transpose_3x3(int mm)
{
int idx = MMODE_IDX(mm);
int top = stack_top[idx];
float *m1 = mat_stack[idx][top];
float determinant = +m1[M4(0,0)]*(m1[M4(1,1)]*m1[M4(2,2)]-m1[M4(2,1)]*m1[M4(1,2)])
-m1[M4(0,1)]*(m1[M4(1,0)]*m1[M4(2,2)]-m1[M4(1,2)]*m1[M4(2,0)])
+m1[M4(0,2)]*(m1[M4(1,0)]*m1[M4(2,1)]-m1[M4(1,1)]*m1[M4(2,0)]);
float invdet = 1/determinant;
inv_transpose_result[M3(0,0)] = (m1[M4(1,1)]*m1[M4(2,2)]-m1[M4(2,1)]*m1[M4(1,2)])*invdet;
inv_transpose_result[M3(1,0)] = -(m1[M4(0,1)]*m1[M4(2,2)]-m1[M4(0,2)]*m1[M4(2,1)])*invdet;
inv_transpose_result[M3(2,0)] = (m1[M4(0,1)]*m1[M4(1,2)]-m1[M4(0,2)]*m1[M4(1,1)])*invdet;
inv_transpose_result[M3(0,1)] = -(m1[M4(1,0)]*m1[M4(2,2)]-m1[M4(1,2)]*m1[M4(2,0)])*invdet;
inv_transpose_result[M3(1,1)] = (m1[M4(0,0)]*m1[M4(2,2)]-m1[M4(0,2)]*m1[M4(2,0)])*invdet;
inv_transpose_result[M3(2,1)] = -(m1[M4(0,0)]*m1[M4(1,2)]-m1[M4(1,0)]*m1[M4(0,2)])*invdet;
inv_transpose_result[M3(0,2)] = (m1[M4(1,0)]*m1[M4(2,1)]-m1[M4(2,0)]*m1[M4(1,1)])*invdet;
inv_transpose_result[M3(1,2)] = -(m1[M4(0,0)]*m1[M4(2,1)]-m1[M4(2,0)]*m1[M4(0,1)])*invdet;
inv_transpose_result[M3(2,2)] = (m1[M4(0,0)]*m1[M4(1,1)]-m1[M4(1,0)]*m1[M4(0,1)])*invdet;
return inv_transpose_result;
}

View File

@ -0,0 +1,31 @@
#ifndef GLMATRIX_H_
#define GLMATRIX_H_
#ifndef GL_MODELVIEW
#define GL_MODELVIEW 0x1700
#endif
#ifndef GL_PROJECTION
#define GL_PROJECTION 0x1701
#endif
#ifndef GL_TEXTURE
#define GL_TEXTURE 0x1702
#endif
void gl_matrix_mode(int mmode);
void gl_push_matrix(void);
void gl_pop_matrix(void);
void gl_load_identity(void);
void gl_load_matrixf(const float *mat);
void gl_mult_matrixf(const float *mat);
void gl_translatef(float x, float y, float z);
void gl_rotatef(float angle, float x, float y, float z);
void gl_scalef(float x, float y, float z);
void gl_ortho(float left, float right, float bottom, float top, float znear, float zfar);
void gl_frustum(float left, float right, float bottom, float top, float znear, float zfar);
void glu_perspective(float vfov, float aspect, float znear, float zfar);
/* getters */
float* get_matrix(int mm);
float* get_inv_transpose_3x3(int mm);
#endif /* GLMATRIX_H_ */

946
progs/demos/shapes/shapes.c Normal file
View File

@ -0,0 +1,946 @@
/*! \file shapes.c
\ingroup demos
This program is a test harness for the various shapes
in OpenGLUT. It may also be useful to see which
parameters control what behavior in the OpenGLUT
objects.
Spinning wireframe and solid-shaded shapes are
displayed. Some parameters can be adjusted.
Keys:
- <tt>Esc &nbsp;</tt> Quit
- <tt>q Q &nbsp;</tt> Quit
- <tt>i I &nbsp;</tt> Show info
- <tt>p P &nbsp;</tt> Toggle perspective or orthographic projection
- <tt>r R &nbsp;</tt> Toggle fixed or animated rotation around model X-axis
- <tt>s S &nbsp;</tt> Toggle toggle fixed function or shader render path
- <tt>n N &nbsp;</tt> Toggle visualization of object's normal vectors
- <tt>= + &nbsp;</tt> Increase \a slices
- <tt>- _ &nbsp;</tt> Decreate \a slices
- <tt>, < &nbsp;</tt> Decreate \a stacks
- <tt>. > &nbsp;</tt> Increase \a stacks
- <tt>9 ( &nbsp;</tt> Decreate \a depth (Sierpinski Sponge)
- <tt>0 ) &nbsp;</tt> Increase \a depth (Sierpinski Sponge)
- <tt>up&nbsp; &nbsp;</tt> Increase "outer radius"
- <tt>down&nbsp;</tt> Decrease "outer radius"
- <tt>left&nbsp;</tt> Decrease "inner radius"
- <tt>right</tt> Increase "inner radius"
- <tt>PgUp&nbsp;</tt> Next shape-drawing function
- <tt>PgDn&nbsp;</tt> Prev shape-drawing function
\author Written by Nigel Stewart November 2003
\author Portions Copyright (C) 2004, the OpenGLUT project contributors. <br>
OpenGLUT branched from freeglut in February, 2004.
\image html openglut_shapes.png OpenGLUT Geometric Shapes Demonstration
\include demos/shapes/shapes.c
*/
#include <GL/freeglut.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include "glmatrix.h"
#ifdef _MSC_VER
/* DUMP MEMORY LEAKS */
#include <crtdbg.h>
#endif
/* report GL errors, if any, to stderr */
void checkError(const char *functionName)
{
GLenum error;
while (( error = glGetError() ) != GL_NO_ERROR) {
fprintf (stderr, "GL error 0x%X detected in %s\n", error, functionName);
}
}
/*
* OpenGL 2+ shader mode needs some function and macro definitions,
* avoiding a dependency on additional libraries like GLEW or the
* GL/glext.h header
*/
#ifndef GL_FRAGMENT_SHADER
#define GL_FRAGMENT_SHADER 0x8B30
#endif
#ifndef GL_VERTEX_SHADER
#define GL_VERTEX_SHADER 0x8B31
#endif
#ifndef GL_COMPILE_STATUS
#define GL_COMPILE_STATUS 0x8B81
#endif
#ifndef GL_LINK_STATUS
#define GL_LINK_STATUS 0x8B82
#endif
#ifndef GL_INFO_LOG_LENGTH
#define GL_INFO_LOG_LENGTH 0x8B84
#endif
typedef ptrdiff_t ourGLsizeiptr;
typedef char ourGLchar;
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef GL_VERSION_2_0
typedef GLuint (APIENTRY *PFNGLCREATESHADERPROC) (GLenum type);
typedef void (APIENTRY *PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const ourGLchar **string, const GLint *length);
typedef void (APIENTRY *PFNGLCOMPILESHADERPROC) (GLuint shader);
typedef GLuint (APIENTRY *PFNGLCREATEPROGRAMPROC) (void);
typedef void (APIENTRY *PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
typedef void (APIENTRY *PFNGLLINKPROGRAMPROC) (GLuint program);
typedef void (APIENTRY *PFNGLUSEPROGRAMPROC) (GLuint program);
typedef void (APIENTRY *PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
typedef void (APIENTRY *PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, ourGLchar *infoLog);
typedef void (APIENTRY *PFNGLGETPROGRAMIVPROC) (GLenum target, GLenum pname, GLint *params);
typedef void (APIENTRY *PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, ourGLchar *infoLog);
typedef GLint (APIENTRY *PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const ourGLchar *name);
typedef GLint (APIENTRY *PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const ourGLchar *name);
typedef void (APIENTRY *PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
typedef void (APIENTRY *PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
#endif
PFNGLCREATESHADERPROC gl_CreateShader;
PFNGLSHADERSOURCEPROC gl_ShaderSource;
PFNGLCOMPILESHADERPROC gl_CompileShader;
PFNGLCREATEPROGRAMPROC gl_CreateProgram;
PFNGLATTACHSHADERPROC gl_AttachShader;
PFNGLLINKPROGRAMPROC gl_LinkProgram;
PFNGLUSEPROGRAMPROC gl_UseProgram;
PFNGLGETSHADERIVPROC gl_GetShaderiv;
PFNGLGETSHADERINFOLOGPROC gl_GetShaderInfoLog;
PFNGLGETPROGRAMIVPROC gl_GetProgramiv;
PFNGLGETPROGRAMINFOLOGPROC gl_GetProgramInfoLog;
PFNGLGETATTRIBLOCATIONPROC gl_GetAttribLocation;
PFNGLGETUNIFORMLOCATIONPROC gl_GetUniformLocation;
PFNGLUNIFORMMATRIX4FVPROC gl_UniformMatrix4fv;
PFNGLUNIFORMMATRIX3FVPROC gl_UniformMatrix3fv;
void initExtensionEntries(void)
{
gl_CreateShader = (PFNGLCREATESHADERPROC) glutGetProcAddress ("glCreateShader");
gl_ShaderSource = (PFNGLSHADERSOURCEPROC) glutGetProcAddress ("glShaderSource");
gl_CompileShader = (PFNGLCOMPILESHADERPROC) glutGetProcAddress ("glCompileShader");
gl_CreateProgram = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress ("glCreateProgram");
gl_AttachShader = (PFNGLATTACHSHADERPROC) glutGetProcAddress ("glAttachShader");
gl_LinkProgram = (PFNGLLINKPROGRAMPROC) glutGetProcAddress ("glLinkProgram");
gl_UseProgram = (PFNGLUSEPROGRAMPROC) glutGetProcAddress ("glUseProgram");
gl_GetShaderiv = (PFNGLGETSHADERIVPROC) glutGetProcAddress ("glGetShaderiv");
gl_GetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) glutGetProcAddress ("glGetShaderInfoLog");
gl_GetProgramiv = (PFNGLGETPROGRAMIVPROC) glutGetProcAddress ("glGetProgramiv");
gl_GetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) glutGetProcAddress ("glGetProgramInfoLog");
gl_GetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) glutGetProcAddress ("glGetAttribLocation");
gl_GetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress ("glGetUniformLocation");
gl_UniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) glutGetProcAddress ("glUniformMatrix4fv");
gl_UniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) glutGetProcAddress ("glUniformMatrix3fv");
if (!gl_CreateShader || !gl_ShaderSource || !gl_CompileShader || !gl_CreateProgram || !gl_AttachShader || !gl_LinkProgram || !gl_UseProgram || !gl_GetShaderiv || !gl_GetShaderInfoLog || !gl_GetProgramiv || !gl_GetProgramInfoLog || !gl_GetAttribLocation || !gl_GetUniformLocation || !gl_UniformMatrix4fv || !gl_UniformMatrix3fv)
{
fprintf (stderr, "glCreateShader, glShaderSource, glCompileShader, glCreateProgram, glAttachShader, glLinkProgram, glUseProgram, glGetShaderiv, glGetShaderInfoLog, glGetProgramiv, glGetProgramInfoLog, glGetAttribLocation, glGetUniformLocation, glUniformMatrix4fv or gl_UniformMatrix3fv not found");
exit(1);
}
}
const ourGLchar *vertexShaderSource[] = {
"/**",
" * From the OpenGL Programming wikibook: http://en.wikibooks.org/wiki/GLSL_Programming/GLUT/Smooth_Specular_Highlights",
" * This file is in the public domain.",
" * Contributors: Sylvain Beucler",
" */",
"attribute vec3 fg_coord;",
"attribute vec3 fg_normal;",
"varying vec4 position; /* position of the vertex (and fragment) in world space */",
"varying vec3 varyingNormalDirection; /* surface normal vector in world space */",
"uniform mat4 m, p; /* don't need v, as always identity in our demo */",
"uniform mat3 m_3x3_inv_transp;",
" ",
"void main()",
"{",
" vec4 fg_coord4 = vec4(fg_coord, 1.0);",
" position = m * fg_coord4;",
" varyingNormalDirection = normalize(m_3x3_inv_transp * fg_normal);",
" ",
" mat4 mvp = p*m; /* normally p*v*m */",
" gl_Position = mvp * fg_coord4;",
"}"
};
const ourGLchar *fragmentShaderSource[] = {
"/**",
" * From the OpenGL Programming wikibook: http://en.wikibooks.org/wiki/GLSL_Programming/GLUT/Smooth_Specular_Highlights",
" * This file is in the public domain.",
" * Contributors: Martin Kraus, Sylvain Beucler",
" */",
"varying vec4 position; /* position of the vertex (and fragment) in world space */",
"varying vec3 varyingNormalDirection; /* surface normal vector in world space */",
"/* uniform mat4 v_inv; // in this demo, the view matrix is always an identity matrix */",
" ",
"struct lightSource",
"{",
" vec4 position;",
" vec4 diffuse;",
" vec4 specular;",
" float constantAttenuation, linearAttenuation, quadraticAttenuation;",
" float spotCutoff, spotExponent;",
" vec3 spotDirection;",
"};",
"lightSource light0 = lightSource(",
" vec4(2.0, 5.0, 5.0, 0.0),",
" vec4(1.0, 1.0, 1.0, 1.0),",
" vec4(1.0, 1.0, 1.0, 1.0),",
" 0.0, 1.0, 0.0,",
" 180.0, 0.0,",
" vec3(0.0, 0.0, 0.0)",
");",
"vec4 scene_ambient = vec4(0.2, 0.2, 0.2, 1.0);",
" ",
"struct material",
"{",
" vec4 ambient;",
" vec4 diffuse;",
" vec4 specular;",
" float shininess;",
"};",
"material frontMaterial = material(",
" vec4(1.0, 0.0, 0.0, 1.0),",
" vec4(1.0, 0.0, 0.0, 1.0),",
" vec4(1.0, 1.0, 1.0, 1.0),",
" 100.0",
");",
" ",
"void main()",
"{",
" vec3 normalDirection = normalize(varyingNormalDirection);",
" /* vec3 viewDirection = normalize(vec3(v_inv * vec4(0.0, 0.0, 0.0, 1.0) - position)); */",
" vec3 viewDirection = normalize(vec3(vec4(0.0, 0.0, 0.0, 1.0) - position)); /* in this demo, the view matrix is always an identity matrix */",
" vec3 lightDirection;",
" float attenuation;",
" ",
" if (0.0 == light0.position.w) /* directional light? */",
" {",
" attenuation = 1.0; /* no attenuation */",
" lightDirection = normalize(vec3(light0.position));",
" } ",
" else /* point light or spotlight (or other kind of light) */",
" {",
" vec3 positionToLightSource = vec3(light0.position - position);",
" float distance = length(positionToLightSource);",
" lightDirection = normalize(positionToLightSource);",
" attenuation = 1.0 / (light0.constantAttenuation",
" + light0.linearAttenuation * distance",
" + light0.quadraticAttenuation * distance * distance);",
" ",
" if (light0.spotCutoff <= 90.0) /* spotlight? */",
" {",
" float clampedCosine = max(0.0, dot(-lightDirection, light0.spotDirection));",
" if (clampedCosine < cos(radians(light0.spotCutoff))) /* outside of spotlight cone? */",
" {",
" attenuation = 0.0;",
" }",
" else",
" {",
" attenuation = attenuation * pow(clampedCosine, light0.spotExponent); ",
" }",
" }",
" }",
" ",
" vec3 ambientLighting = vec3(scene_ambient) * vec3(frontMaterial.ambient);",
" ",
" vec3 diffuseReflection = attenuation ",
" * vec3(light0.diffuse) * vec3(frontMaterial.diffuse)",
" * max(0.0, dot(normalDirection, lightDirection));",
" ",
" vec3 specularReflection;",
" if (dot(normalDirection, lightDirection) < 0.0) /* light source on the wrong side? */",
" {",
" specularReflection = vec3(0.0, 0.0, 0.0); /* no specular reflection */",
" }",
" else /* light source on the right side */",
" {",
" specularReflection = attenuation * vec3(light0.specular) * vec3(frontMaterial.specular) ",
" * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), frontMaterial.shininess);",
" }",
" ",
" gl_FragColor = vec4(ambientLighting + diffuseReflection + specularReflection, 1.0);",
"}"
};
GLint getAttribOrUniformLocation(const char* name, GLuint program, GLboolean isAttrib)
{
if (isAttrib)
{
GLint attrib = gl_GetAttribLocation(program, name);
if (attrib == -1)
{
fprintf(stderr, "Warning: Could not bind attrib %s\n", name);
}
checkError ("getAttribOrUniformLocation");
return attrib;
}
else
{
GLint uniform = gl_GetUniformLocation(program, name);
if (uniform == -1)
{
fprintf(stderr, "Warning: Could not bind uniform %s\n", name);
}
checkError ("getAttribOrUniformLocation");
return uniform;
}
}
GLuint program;
GLint attribute_fg_coord = -1, attribute_fg_normal = -1;
GLint uniform_m = -1, uniform_p = -1, uniform_m_3x3_inv_transp = -1;
GLint shaderReady = 0; /* Set to 1 when all initialization went well, to -1 when shader somehow unusable. */
void compileAndCheck(GLuint shader)
{
GLint status;
gl_CompileShader (shader);
gl_GetShaderiv (shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
GLint infoLogLength;
ourGLchar *infoLog;
gl_GetShaderiv (shader, GL_INFO_LOG_LENGTH, &infoLogLength);
infoLog = (ourGLchar*) malloc (infoLogLength);
gl_GetShaderInfoLog (shader, infoLogLength, NULL, infoLog);
fprintf (stderr, "compile log: %s\n", infoLog);
free (infoLog);
}
checkError ("compileAndCheck");
}
GLuint compileShaderSource(GLenum type, GLsizei count, const ourGLchar **string)
{
GLuint shader = gl_CreateShader (type);
gl_ShaderSource (shader, count, string, NULL);
checkError ("compileShaderSource");
compileAndCheck (shader);
return shader;
}
void linkAndCheck(GLuint program)
{
GLint status;
gl_LinkProgram (program);
gl_GetProgramiv (program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
GLint infoLogLength;
ourGLchar *infoLog;
gl_GetProgramiv (program, GL_INFO_LOG_LENGTH, &infoLogLength);
infoLog = (ourGLchar*) malloc (infoLogLength);
gl_GetProgramInfoLog (program, infoLogLength, NULL, infoLog);
fprintf (stderr, "link log: %s\n", infoLog);
free (infoLog);
}
checkError ("linkAndCheck");
}
void createProgram(GLuint vertexShader, GLuint fragmentShader)
{
program = gl_CreateProgram ();
if (vertexShader != 0) {
gl_AttachShader (program, vertexShader);
}
if (fragmentShader != 0) {
gl_AttachShader (program, fragmentShader);
}
checkError ("createProgram");
linkAndCheck (program);
}
void initShader(void)
{
const GLsizei vertexShaderLines = sizeof(vertexShaderSource) / sizeof(ourGLchar*);
GLuint vertexShader =
compileShaderSource (GL_VERTEX_SHADER, vertexShaderLines, vertexShaderSource);
const GLsizei fragmentShaderLines = sizeof(fragmentShaderSource) / sizeof(ourGLchar*);
GLuint fragmentShader =
compileShaderSource (GL_FRAGMENT_SHADER, fragmentShaderLines, fragmentShaderSource);
checkError ("initShader - 1");
createProgram (vertexShader, fragmentShader);
gl_UseProgram (program);
attribute_fg_coord = getAttribOrUniformLocation("fg_coord" , program, GL_TRUE);
attribute_fg_normal = getAttribOrUniformLocation("fg_normal" , program, GL_TRUE);
uniform_m = getAttribOrUniformLocation("m" , program, GL_FALSE);
uniform_p = getAttribOrUniformLocation("p" , program, GL_FALSE);
uniform_m_3x3_inv_transp= getAttribOrUniformLocation("m_3x3_inv_transp" , program, GL_FALSE);
gl_UseProgram (0);
if (attribute_fg_coord==-1 || attribute_fg_normal==-1 ||
uniform_m==-1 || uniform_p==-1 || uniform_m_3x3_inv_transp==-1)
shaderReady = -1;
else
shaderReady = 1;
checkError ("initShader - 2");
}
/*
* This macro is only intended to be used on arrays, of course.
*/
#define NUMBEROF(x) ((sizeof(x))/(sizeof(x[0])))
/*
* These global variables control which object is drawn,
* and how it is drawn. No object uses all of these
* variables.
*/
static int function_index;
static int slices = 16;
static int stacks = 16;
static double irad = .25;
static double orad = 1.0; /* doubles as size for objects other than Torus */
static int depth = 4;
static double offset[ 3 ] = { 0, 0, 0 };
static GLboolean show_info = GL_TRUE;
static float ar;
static GLboolean persProject = GL_TRUE;
static GLboolean animateXRot = GL_FALSE;
static GLboolean useShader = GL_FALSE;
static GLboolean visNormals = GL_FALSE;
static GLboolean flat;
/*
* Enum to tell drawSizeInfo what to draw for each object
*/
#define GEO_NO_SIZE 0
#define GEO_SIZE 1
#define GEO_SCALE 2
#define GEO_INNER_OUTER_RAD 4
#define GEO_RAD 8
#define GEO_BASE_HEIGHT 16
#define GEO_RAD_HEIGHT 32
/*
* These one-liners draw particular objects, fetching appropriate
* information from the above globals. They are just thin wrappers
* for the FreeGLUT objects.
*/
static void drawSolidTetrahedron(void) { glutSolidTetrahedron (); }
static void drawWireTetrahedron(void) { glutWireTetrahedron (); }
static void drawSolidCube(void) { glutSolidCube(orad); } /* orad doubles as size input */
static void drawWireCube(void) { glutWireCube(orad); } /* orad doubles as size input */
static void drawSolidOctahedron(void) { glutSolidOctahedron (); }
static void drawWireOctahedron(void) { glutWireOctahedron (); }
static void drawSolidDodecahedron(void) { glutSolidDodecahedron (); }
static void drawWireDodecahedron(void) { glutWireDodecahedron (); }
static void drawSolidRhombicDodecahedron(void) { glutSolidRhombicDodecahedron (); }
static void drawWireRhombicDodecahedron(void) { glutWireRhombicDodecahedron (); }
static void drawSolidIcosahedron(void) { glutSolidIcosahedron (); }
static void drawWireIcosahedron(void) { glutWireIcosahedron (); }
static void drawSolidSierpinskiSponge(void) { glutSolidSierpinskiSponge (depth, offset, orad);} /* orad doubles as size input */
static void drawWireSierpinskiSponge(void) { glutWireSierpinskiSponge (depth, offset, orad); } /* orad doubles as size input */
static void drawSolidTorus(void) { glutSolidTorus(irad,orad,slices,stacks); }
static void drawWireTorus(void) { glutWireTorus (irad,orad,slices,stacks); }
static void drawSolidSphere(void) { glutSolidSphere(orad,slices,stacks); } /* orad doubles as size input */
static void drawWireSphere(void) { glutWireSphere(orad,slices,stacks); } /* orad doubles as size input */
static void drawSolidCone(void) { glutSolidCone(irad,orad,slices,stacks); } /* irad doubles as base input, and orad as height input */
static void drawWireCone(void) { glutWireCone(irad,orad,slices,stacks); } /* irad doubles as base input, and orad as height input */
static void drawSolidCylinder(void) { glutSolidCylinder(irad,orad,slices,stacks); } /* irad doubles as radius input, and orad as height input */
static void drawWireCylinder(void) { glutWireCylinder(irad,orad,slices,stacks); } /* irad doubles as radius input, and orad as height input */
/* per Glut manpage, it should be noted that the teapot is rendered
* with clockwise winding for front facing polygons...
* Same for the teacup and teaspoon
*/
static void drawSolidTeapot(void)
{ glFrontFace(GL_CW); glutSolidTeapot(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
static void drawWireTeapot(void)
{ glFrontFace(GL_CW); glutWireTeapot(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
static void drawSolidTeacup(void)
{ glFrontFace(GL_CW); glutSolidTeacup(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
static void drawWireTeacup(void)
{ glFrontFace(GL_CW); glutWireTeacup(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
static void drawSolidTeaspoon(void)
{ glFrontFace(GL_CW); glutSolidTeaspoon(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
static void drawWireTeaspoon(void)
{ glFrontFace(GL_CW); glutWireTeaspoon(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
#define RADIUSFAC 0.70710678118654752440084436210485f
static void drawSolidCuboctahedron(void)
{
GLfloat radius = RADIUSFAC*(GLfloat)orad; /* orad doubles as size */
glBegin( GL_TRIANGLES );
glNormal3d( 0.577350269189, 0.577350269189, 0.577350269189); glVertex3d( radius, radius, 0.0 ); glVertex3d( 0.0, radius, radius ); glVertex3d( radius, 0.0, radius );
glNormal3d( 0.577350269189, 0.577350269189,-0.577350269189); glVertex3d( radius, radius, 0.0 ); glVertex3d( radius, 0.0,-radius ); glVertex3d( 0.0, radius,-radius );
glNormal3d( 0.577350269189,-0.577350269189, 0.577350269189); glVertex3d( radius,-radius, 0.0 ); glVertex3d( radius, 0.0, radius ); glVertex3d( 0.0,-radius, radius );
glNormal3d( 0.577350269189,-0.577350269189,-0.577350269189); glVertex3d( radius,-radius, 0.0 ); glVertex3d( 0.0,-radius,-radius ); glVertex3d( radius, 0.0,-radius );
glNormal3d(-0.577350269189, 0.577350269189, 0.577350269189); glVertex3d(-radius, radius, 0.0 ); glVertex3d(-radius, 0.0, radius ); glVertex3d( 0.0, radius, radius );
glNormal3d(-0.577350269189, 0.577350269189,-0.577350269189); glVertex3d(-radius, radius, 0.0 ); glVertex3d( 0.0, radius,-radius ); glVertex3d(-radius, 0.0,-radius );
glNormal3d(-0.577350269189,-0.577350269189, 0.577350269189); glVertex3d(-radius,-radius, 0.0 ); glVertex3d( 0.0,-radius, radius ); glVertex3d(-radius, 0.0, radius );
glNormal3d(-0.577350269189,-0.577350269189,-0.577350269189); glVertex3d(-radius,-radius, 0.0 ); glVertex3d(-radius, 0.0,-radius ); glVertex3d( 0.0,-radius,-radius );
glEnd();
glBegin( GL_QUADS );
glNormal3d( 1.0, 0.0, 0.0 ); glVertex3d( radius, radius, 0.0 ); glVertex3d( radius, 0.0, radius ); glVertex3d( radius,-radius, 0.0 ); glVertex3d( radius, 0.0,-radius );
glNormal3d(-1.0, 0.0, 0.0 ); glVertex3d(-radius, radius, 0.0 ); glVertex3d(-radius, 0.0,-radius ); glVertex3d(-radius,-radius, 0.0 ); glVertex3d(-radius, 0.0, radius );
glNormal3d( 0.0, 1.0, 0.0 ); glVertex3d( radius, radius, 0.0 ); glVertex3d( 0.0, radius,-radius ); glVertex3d(-radius, radius, 0.0 ); glVertex3d( 0.0, radius, radius );
glNormal3d( 0.0,-1.0, 0.0 ); glVertex3d( radius,-radius, 0.0 ); glVertex3d( 0.0,-radius, radius ); glVertex3d(-radius,-radius, 0.0 ); glVertex3d( 0.0,-radius,-radius );
glNormal3d( 0.0, 0.0, 1.0 ); glVertex3d( radius, 0.0, radius ); glVertex3d( 0.0, radius, radius ); glVertex3d(-radius, 0.0, radius ); glVertex3d( 0.0,-radius, radius );
glNormal3d( 0.0, 0.0,-1.0 ); glVertex3d( radius, 0.0,-radius ); glVertex3d( 0.0,-radius,-radius ); glVertex3d(-radius, 0.0,-radius ); glVertex3d( 0.0, radius,-radius );
glEnd();
}
static void drawWireCuboctahedron(void)
{
GLfloat radius = RADIUSFAC*(GLfloat)orad; /* orad doubles as size */
glBegin( GL_LINE_LOOP );
glNormal3d( 1.0, 0.0, 0.0 ); glVertex3d( radius, radius, 0.0 ); glVertex3d( radius, 0.0, radius ); glVertex3d( radius,-radius, 0.0 ); glVertex3d( radius, 0.0,-radius );
glEnd();
glBegin( GL_LINE_LOOP );
glNormal3d(-1.0, 0.0, 0.0 ); glVertex3d(-radius, radius, 0.0 ); glVertex3d(-radius, 0.0,-radius ); glVertex3d(-radius,-radius, 0.0 ); glVertex3d(-radius, 0.0, radius );
glEnd();
glBegin( GL_LINE_LOOP );
glNormal3d( 0.0, 1.0, 0.0 ); glVertex3d( radius, radius, 0.0 ); glVertex3d( 0.0, radius,-radius ); glVertex3d(-radius, radius, 0.0 ); glVertex3d( 0.0, radius, radius );
glEnd();
glBegin( GL_LINE_LOOP );
glNormal3d( 0.0,-1.0, 0.0 ); glVertex3d( radius,-radius, 0.0 ); glVertex3d( 0.0,-radius, radius ); glVertex3d(-radius,-radius, 0.0 ); glVertex3d( 0.0,-radius,-radius );
glEnd();
glBegin( GL_LINE_LOOP );
glNormal3d( 0.0, 0.0, 1.0 ); glVertex3d( radius, 0.0, radius ); glVertex3d( 0.0, radius, radius ); glVertex3d(-radius, 0.0, radius ); glVertex3d( 0.0,-radius, radius );
glEnd();
glBegin( GL_LINE_LOOP );
glNormal3d( 0.0, 0.0,-1.0 ); glVertex3d( radius, 0.0,-radius ); glVertex3d( 0.0,-radius,-radius ); glVertex3d(-radius, 0.0,-radius ); glVertex3d( 0.0, radius,-radius );
glEnd();
}
#undef RADIUSFAC
/*
* This structure defines an entry in our function-table.
*/
typedef struct
{
const char * const name;
void (*solid) (void);
void (*wire) (void);
int drawSizeInfoFlag;
} entry;
#define ENTRY(e,f) {#e, drawSolid##e, drawWire##e,f}
static const entry table [] =
{
ENTRY (Tetrahedron,GEO_NO_SIZE),
ENTRY (Cube,GEO_SIZE),
ENTRY (Octahedron,GEO_NO_SIZE),
ENTRY (Dodecahedron,GEO_NO_SIZE),
ENTRY (RhombicDodecahedron,GEO_NO_SIZE),
ENTRY (Icosahedron,GEO_NO_SIZE),
ENTRY (SierpinskiSponge,GEO_SCALE),
ENTRY (Teapot,GEO_SIZE),
ENTRY (Teacup,GEO_SIZE),
ENTRY (Teaspoon,GEO_SIZE),
ENTRY (Torus,GEO_INNER_OUTER_RAD),
ENTRY (Sphere,GEO_RAD),
ENTRY (Cone,GEO_BASE_HEIGHT),
ENTRY (Cylinder,GEO_RAD_HEIGHT),
ENTRY (Cuboctahedron,GEO_SIZE) /* This one doesn't work when in shader mode and is then skipped */
};
#undef ENTRY
/*!
Does printf()-like work using freeglut
glutBitmapString(). Uses a fixed font. Prints
at the indicated row/column position.
Limitation: Cannot address pixels.
Limitation: Renders in screen coords, not model coords.
*/
static void shapesPrintf (int row, int col, const char *fmt, ...)
{
static char buf[256];
int viewport[4];
void *font = GLUT_BITMAP_9_BY_15;
va_list args;
va_start(args, fmt);
#if defined(WIN32) && !defined(__CYGWIN__)
(void) _vsnprintf (buf, sizeof(buf), fmt, args);
#else
(void) vsnprintf (buf, sizeof(buf), fmt, args);
#endif
va_end(args);
glGetIntegerv(GL_VIEWPORT,viewport);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0,viewport[2],0,viewport[3],-1,1);
glRasterPos2i
(
glutBitmapWidth(font, ' ') * col,
- glutBitmapHeight(font) * row + viewport[3]
);
glutBitmapString (font, (unsigned char*)buf);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
/* Print info about the about the current shape and render state on the screen */
static void DrawSizeInfo(int *row)
{
switch (table [function_index].drawSizeInfoFlag)
{
case GEO_NO_SIZE:
break;
case GEO_SIZE:
shapesPrintf ((*row)++, 1, "Size Up Down : %f", orad);
break;
case GEO_SCALE:
shapesPrintf ((*row)++, 1, "Scale Up Down : %f", orad);
break;
case GEO_INNER_OUTER_RAD:
shapesPrintf ((*row)++, 1, "Inner radius Left Right: %f", irad);
shapesPrintf ((*row)++, 1, "Outer radius Up Down : %f", orad);
break;
case GEO_RAD:
shapesPrintf ((*row)++, 1, "Radius Up Down : %f", orad);
break;
case GEO_BASE_HEIGHT:
shapesPrintf ((*row)++, 1, "Base Left Right: %f", irad);
shapesPrintf ((*row)++, 1, "Height Up Down : %f", orad);
break;
case GEO_RAD_HEIGHT:
shapesPrintf ((*row)++, 1, "Radius Left Right: %f", irad);
shapesPrintf ((*row)++, 1, "Height Up Down : %f", orad);
break;
}
}
static void drawInfo()
{
int row = 1;
shapesPrintf (row++, 1, "Shape PgUp PgDn: %s", table [function_index].name);
shapesPrintf (row++, 1, "Slices +-: %d Stacks <>: %d", slices, stacks);
shapesPrintf (row++, 1, "nSides +-: %d nRings <>: %d", slices, stacks);
shapesPrintf (row++, 1, "Depth (): %d", depth);
DrawSizeInfo(&row);
if (persProject)
shapesPrintf (row++, 1, "Perspective projection (p)");
else
shapesPrintf (row++, 1, "Orthographic projection (p)");
if (useShader) {
shapesPrintf (row++, 1, "Using shader (s)");
} else {
shapesPrintf (row++, 1, "Using fixed function pipeline (s)");
if (flat)
shapesPrintf (row++, 1, "Flat shading (f)");
else
shapesPrintf (row++, 1, "Smooth shading (f)");
}
if (animateXRot)
shapesPrintf (row++, 1, "2D rotation (r)");
else
shapesPrintf (row++, 1, "1D rotation (r)");
shapesPrintf (row++, 1, "visualizing normals: %i (n)",visNormals);
}
/* GLUT callback Handlers */
static void
resize(int width, int height)
{
ar = (float) width / (float) height;
glViewport(0, 0, width, height);
}
static void display(void)
{
const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
const double a = t*89.0;
const double b = (animateXRot?t:1)*67.0;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSetOption(GLUT_GEOMETRY_VISUALIZE_NORMALS,visNormals); /* Normals visualized or not? */
glShadeModel(flat ? GL_FLAT : GL_SMOOTH); /* flat or gouraud shading */
if (useShader && !shaderReady)
initShader();
if (useShader && shaderReady)
{
/* setup use of shader (and vertex buffer by FreeGLUT) */
gl_UseProgram (program);
glutSetVertexAttribCoord3(attribute_fg_coord);
glutSetVertexAttribNormal(attribute_fg_normal);
/* There is also a glutSetVertexAttribTexCoord2, which is used only when drawing the teapot, teacup or teaspoon */
gl_matrix_mode(GL_PROJECTION);
gl_load_identity();
if (persProject)
gl_frustum(-ar, ar, -1.f, 1.f, 2.f, 100.f);
else
gl_ortho(-ar*3, ar*3, -3.f, 3.f, 2.f, 100.f);
gl_UniformMatrix4fv (uniform_p, 1, GL_FALSE, get_matrix(GL_PROJECTION));
gl_matrix_mode(GL_MODELVIEW);
gl_load_identity();
gl_push_matrix();
/* Not in reverse order like normal OpenGL, our util library multiplies the matrices in the order they are specified in */
gl_rotatef((float)a,0,0,1);
gl_rotatef((float)b,1,0,0);
gl_translatef(0,1.2f,-6);
gl_UniformMatrix4fv (uniform_m , 1, GL_FALSE, get_matrix(GL_MODELVIEW));
gl_UniformMatrix3fv (uniform_m_3x3_inv_transp, 1, GL_FALSE, get_inv_transpose_3x3(GL_MODELVIEW));
table [function_index].solid ();
gl_pop_matrix();
gl_push_matrix();
gl_rotatef((float)a,0,0,1);
gl_rotatef((float)b,1,0,0);
gl_translatef(0,-1.2f,-6);
gl_UniformMatrix4fv (uniform_m , 1, GL_FALSE, get_matrix(GL_MODELVIEW));
gl_UniformMatrix3fv (uniform_m_3x3_inv_transp, 1, GL_FALSE, get_inv_transpose_3x3(GL_MODELVIEW));
table [function_index].wire ();
gl_pop_matrix();
gl_UseProgram (0);
glutSetVertexAttribCoord3(-1);
glutSetVertexAttribNormal(-1);
checkError ("display");
}
else
{
/* fixed function pipeline */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (persProject)
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
else
glOrtho(-ar*3, ar*3, -3.0, 3.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_LIGHTING);
glColor3d(1,0,0);
glPushMatrix();
glTranslated(0,1.2,-6);
glRotated(b,1,0,0);
glRotated(a,0,0,1);
table [function_index].solid ();
glPopMatrix();
glPushMatrix();
glTranslated(0,-1.2,-6);
glRotated(b,1,0,0);
glRotated(a,0,0,1);
table [function_index].wire ();
glPopMatrix();
glDisable(GL_LIGHTING);
glColor3d(0.1,0.1,0.4);
}
if( show_info )
/* print info to screen */
drawInfo();
else
/* print to command line instead */
printf ( "Shape %d slides %d stacks %d\n", function_index, slices, stacks ) ;
glutSwapBuffers();
}
static void
key(unsigned char key, int x, int y)
{
switch (key)
{
case 27 :
case 'Q':
case 'q': glutLeaveMainLoop () ; break;
case 'I':
case 'i': show_info=!show_info; break;
case '=':
case '+': slices++; break;
case '-':
case '_': if( slices > -1 ) slices--; break;
case ',':
case '<': if( stacks > -1 ) stacks--; break;
case '.':
case '>': stacks++; break;
case '9':
case '(': if( depth > -1 ) depth--; break;
case '0':
case ')': ++depth; break;
case 'P':
case 'p': persProject=!persProject; break;
case 'R':
case 'r': animateXRot=!animateXRot; break;
case 'S':
case 's':
useShader=!useShader;
/* Cuboctahedron can't be shown when in shader mode, move to next */
if (useShader && NUMBEROF (table)-1 == ( unsigned )function_index)
function_index = 0;
break;
case 'F':
case 'f':
flat ^= 1;
break;
case 'N':
case 'n': visNormals=!visNormals; break;
default:
break;
}
glutPostRedisplay();
}
static void special (int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_PAGE_UP: ++function_index; break;
case GLUT_KEY_PAGE_DOWN: --function_index; break;
case GLUT_KEY_UP: orad *= 2; break;
case GLUT_KEY_DOWN: orad /= 2; break;
case GLUT_KEY_RIGHT: irad *= 2; break;
case GLUT_KEY_LEFT: irad /= 2; break;
default:
break;
}
if (0 > function_index)
function_index = NUMBEROF (table) - 1;
if (NUMBEROF (table) <= ( unsigned )function_index)
function_index = 0;
/* Cuboctahedron can't be shown when in shader mode, skip it */
if (useShader && NUMBEROF (table)-1 == ( unsigned )function_index)
{
if (key==GLUT_KEY_PAGE_UP)
function_index = 0;
else
function_index -= 1;
}
}
static void
idle(void)
{
glutPostRedisplay();
}
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };
/* Program entry point */
int
main(int argc, char *argv[])
{
glutInitWindowSize(800,600);
glutInitWindowPosition(40,40);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
glutCreateWindow("FreeGLUT Shapes");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutSpecialFunc(special);
glutIdleFunc(idle);
glutSetOption ( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION ) ;
glClearColor(1,1,1,1);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
initExtensionEntries();
glutMainLoop();
#ifdef _MSC_VER
/* DUMP MEMORY LEAK INFORMATION */
_CrtDumpMemoryLeaks () ;
#endif
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,469 @@
/*
* smooth_opengl3.c, based on smooth.c, which is (c) by SGI, see below.
* This program demonstrates smooth shading in a way which is fully
* OpenGL-3.1-compliant.
* A smooth shaded polygon is drawn in a 2-D projection.
*/
/*
* Original copyright notice from smooth.c:
*
* License Applicability. Except to the extent portions of this file are
* made subject to an alternative license as permitted in the SGI Free
* Software License B, Version 1.1 (the "License"), the contents of this
* file are subject only to the provisions of the License. You may not use
* this file except in compliance with the License. You may obtain a copy
* of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
* Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
*
* http://oss.sgi.com/projects/FreeB
*
* Note that, as provided in the License, the Software is distributed on an
* "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
* DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
* CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
* PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
*
* Original Code. The Original Code is: OpenGL Sample Implementation,
* Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
* Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
* Copyright in any portions created by third parties is as indicated
* elsewhere herein. All Rights Reserved.
*
* Additional Notice Provisions: The application programming interfaces
* established by SGI in conjunction with the Original Code are The
* OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
* April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
* 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
* Window System(R) (Version 1.3), released October 19, 1998. This software
* was created using the OpenGL(R) version 1.2.1 Sample Implementation
* published by SGI, but has not been independently verified as being
* compliant with the OpenGL(R) version 1.2.1 Specification.
*
*/
#include <GL/freeglut.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
/* report GL errors, if any, to stderr */
void checkError(const char *functionName)
{
GLenum error;
while (( error = glGetError() ) != GL_NO_ERROR) {
fprintf (stderr, "GL error 0x%X detected in %s\n", error, functionName);
}
}
/* extension #defines, types and entries, avoiding a dependency on additional
libraries like GLEW or the GL/glext.h header */
#ifndef GL_ARRAY_BUFFER
#define GL_ARRAY_BUFFER 0x8892
#endif
#ifndef GL_STATIC_DRAW
#define GL_STATIC_DRAW 0x88E4
#endif
#ifndef GL_FRAGMENT_SHADER
#define GL_FRAGMENT_SHADER 0x8B30
#endif
#ifndef GL_VERTEX_SHADER
#define GL_VERTEX_SHADER 0x8B31
#endif
#ifndef GL_SHADING_LANGUAGE_VERSION
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
#endif
#ifndef GL_COMPILE_STATUS
#define GL_COMPILE_STATUS 0x8B81
#endif
#ifndef GL_LINK_STATUS
#define GL_LINK_STATUS 0x8B82
#endif
#ifndef GL_INFO_LOG_LENGTH
#define GL_INFO_LOG_LENGTH 0x8B84
#endif
typedef ptrdiff_t ourGLsizeiptr;
typedef char ourGLchar;
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef GL_ARB_vertex_array_object
typedef void (APIENTRY *PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
typedef void (APIENTRY *PFNGLBINDVERTEXARRAYPROC) (GLuint array);
#endif
#ifndef GL_VERSION_1_5
typedef void (APIENTRY *PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
typedef void (APIENTRY *PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
typedef void (APIENTRY *PFNGLBUFFERDATAPROC) (GLenum target, ourGLsizeiptr size, const GLvoid *data, GLenum usage);
#endif
#ifndef GL_VERSION_2_0
typedef GLuint (APIENTRY *PFNGLCREATESHADERPROC) (GLenum type);
typedef void (APIENTRY *PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const ourGLchar **string, const GLint *length);
typedef void (APIENTRY *PFNGLCOMPILESHADERPROC) (GLuint shader);
typedef GLuint (APIENTRY *PFNGLCREATEPROGRAMPROC) (void);
typedef void (APIENTRY *PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
typedef void (APIENTRY *PFNGLLINKPROGRAMPROC) (GLuint program);
typedef void (APIENTRY *PFNGLUSEPROGRAMPROC) (GLuint program);
typedef void (APIENTRY *PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
typedef void (APIENTRY *PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, ourGLchar *infoLog);
typedef void (APIENTRY *PFNGLGETPROGRAMIVPROC) (GLenum target, GLenum pname, GLint *params);
typedef void (APIENTRY *PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, ourGLchar *infoLog);
typedef GLint (APIENTRY *PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const ourGLchar *name);
typedef void (APIENTRY *PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRY *PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
typedef GLint (APIENTRY *PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const ourGLchar *name);
typedef void (APIENTRY *PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
#endif
PFNGLGENVERTEXARRAYSPROC gl_GenVertexArrays;
PFNGLBINDVERTEXARRAYPROC gl_BindVertexArray;
PFNGLGENBUFFERSPROC gl_GenBuffers;
PFNGLBINDBUFFERPROC gl_BindBuffer;
PFNGLBUFFERDATAPROC gl_BufferData;
PFNGLCREATESHADERPROC gl_CreateShader;
PFNGLSHADERSOURCEPROC gl_ShaderSource;
PFNGLCOMPILESHADERPROC gl_CompileShader;
PFNGLCREATEPROGRAMPROC gl_CreateProgram;
PFNGLATTACHSHADERPROC gl_AttachShader;
PFNGLLINKPROGRAMPROC gl_LinkProgram;
PFNGLUSEPROGRAMPROC gl_UseProgram;
PFNGLGETSHADERIVPROC gl_GetShaderiv;
PFNGLGETSHADERINFOLOGPROC gl_GetShaderInfoLog;
PFNGLGETPROGRAMIVPROC gl_GetProgramiv;
PFNGLGETPROGRAMINFOLOGPROC gl_GetProgramInfoLog;
PFNGLGETATTRIBLOCATIONPROC gl_GetAttribLocation;
PFNGLVERTEXATTRIBPOINTERPROC gl_VertexAttribPointer;
PFNGLENABLEVERTEXATTRIBARRAYPROC gl_EnableVertexAttribArray;
PFNGLGETUNIFORMLOCATIONPROC gl_GetUniformLocation;
PFNGLUNIFORMMATRIX4FVPROC gl_UniformMatrix4fv;
void initExtensionEntries(void)
{
gl_GenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) glutGetProcAddress ("glGenVertexArrays");
gl_BindVertexArray = (PFNGLBINDVERTEXARRAYPROC) glutGetProcAddress ("glBindVertexArray");
if (!gl_GenVertexArrays || !gl_BindVertexArray)
{
fprintf (stderr, "glGenVertexArrays or glBindVertexArray not found");
exit(1);
}
gl_GenBuffers = (PFNGLGENBUFFERSPROC) glutGetProcAddress ("glGenBuffers");
gl_BindBuffer = (PFNGLBINDBUFFERPROC) glutGetProcAddress ("glBindBuffer");
gl_BufferData = (PFNGLBUFFERDATAPROC) glutGetProcAddress ("glBufferData");
if (!gl_GenBuffers || !gl_BindBuffer || !gl_BufferData)
{
fprintf (stderr, "glGenBuffers, glBindBuffer or glBufferData not found");
exit(1);
}
gl_CreateShader = (PFNGLCREATESHADERPROC) glutGetProcAddress ("glCreateShader");
gl_ShaderSource = (PFNGLSHADERSOURCEPROC) glutGetProcAddress ("glShaderSource");
gl_CompileShader = (PFNGLCOMPILESHADERPROC) glutGetProcAddress ("glCompileShader");
gl_CreateProgram = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress ("glCreateProgram");
gl_AttachShader = (PFNGLATTACHSHADERPROC) glutGetProcAddress ("glAttachShader");
gl_LinkProgram = (PFNGLLINKPROGRAMPROC) glutGetProcAddress ("glLinkProgram");
gl_UseProgram = (PFNGLUSEPROGRAMPROC) glutGetProcAddress ("glUseProgram");
gl_GetShaderiv = (PFNGLGETSHADERIVPROC) glutGetProcAddress ("glGetShaderiv");
gl_GetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) glutGetProcAddress ("glGetShaderInfoLog");
gl_GetProgramiv = (PFNGLGETPROGRAMIVPROC) glutGetProcAddress ("glGetProgramiv");
gl_GetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) glutGetProcAddress ("glGetProgramInfoLog");
gl_GetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) glutGetProcAddress ("glGetAttribLocation");
gl_VertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) glutGetProcAddress ("glVertexAttribPointer");
gl_EnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) glutGetProcAddress ("glEnableVertexAttribArray");
gl_GetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress ("glGetUniformLocation");
gl_UniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) glutGetProcAddress ("glUniformMatrix4fv");
if (!gl_CreateShader || !gl_ShaderSource || !gl_CompileShader || !gl_CreateProgram || !gl_AttachShader || !gl_LinkProgram || !gl_UseProgram || !gl_GetShaderiv || !gl_GetShaderInfoLog || !gl_GetProgramiv || !gl_GetProgramInfoLog || !gl_GetAttribLocation || !gl_VertexAttribPointer || !gl_EnableVertexAttribArray || !gl_GetUniformLocation || !gl_UniformMatrix4fv)
{
fprintf (stderr, "glCreateShader, glShaderSource, glCompileShader, glCreateProgram, glAttachShader, glLinkProgram, glUseProgram, glGetShaderiv, glGetShaderInfoLog, glGetProgramiv, glGetProgramInfoLog, glGetAttribLocation, glVertexAttribPointer, glEnableVertexAttribArray, glGetUniformLocation or glUniformMatrix4fv not found");
exit(1);
}
}
/* vertex array data for a colored 2D triangle, consisting of RGB color values
and XY coordinates */
const GLfloat varray[] = {
1.0f, 0.0f, 0.0f, /* red */
5.0f, 5.0f, /* lower left */
0.0f, 1.0f, 0.0f, /* green */
25.0f, 5.0f, /* lower right */
0.0f, 0.0f, 1.0f, /* blue */
5.0f, 25.0f /* upper left */
};
/* ISO C somehow enforces this silly use of 'enum' for compile-time constants */
enum {
numColorComponents = 3,
numVertexComponents = 2,
stride = sizeof(GLfloat) * (numColorComponents + numVertexComponents),
numElements = sizeof(varray) / stride
};
/* the name of the vertex buffer object */
GLuint vertexBufferName;
GLuint vertexArrayName;
void initBuffer(void)
{
/* Need to setup a vertex array as otherwise invalid operation errors can
* occur when accessing vertex buffer (OpenGL 3.3 has no default zero named
* vertex array)
*/
gl_GenVertexArrays(1, &vertexArrayName);
gl_BindVertexArray(vertexArrayName);
gl_GenBuffers (1, &vertexBufferName);
gl_BindBuffer (GL_ARRAY_BUFFER, vertexBufferName);
gl_BufferData (GL_ARRAY_BUFFER, sizeof(varray), varray, GL_STATIC_DRAW);
checkError ("initBuffer");
}
const ourGLchar *vertexShaderSource[] = {
"#version 140\n",
"uniform mat4 fg_ProjectionMatrix;\n",
"in vec4 fg_Color;\n",
"in vec4 fg_Vertex;\n",
"smooth out vec4 fg_SmoothColor;\n",
"void main()\n",
"{\n",
" fg_SmoothColor = fg_Color;\n",
" gl_Position = fg_ProjectionMatrix * fg_Vertex;\n",
"}\n"
};
const ourGLchar *fragmentShaderSource[] = {
"#version 140\n",
"smooth in vec4 fg_SmoothColor;\n",
"out vec4 fg_FragColor;\n",
"void main(void)\n",
"{\n",
" fg_FragColor = fg_SmoothColor;\n",
"}\n"
};
void compileAndCheck(GLuint shader)
{
GLint status;
gl_CompileShader (shader);
gl_GetShaderiv (shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
GLint infoLogLength;
ourGLchar *infoLog;
gl_GetShaderiv (shader, GL_INFO_LOG_LENGTH, &infoLogLength);
infoLog = (ourGLchar*) malloc (infoLogLength);
gl_GetShaderInfoLog (shader, infoLogLength, NULL, infoLog);
fprintf (stderr, "compile log: %s\n", infoLog);
free (infoLog);
}
}
GLuint compileShaderSource(GLenum type, GLsizei count, const ourGLchar **string)
{
GLuint shader = gl_CreateShader (type);
gl_ShaderSource (shader, count, string, NULL);
compileAndCheck (shader);
return shader;
}
void linkAndCheck(GLuint program)
{
GLint status;
gl_LinkProgram (program);
gl_GetProgramiv (program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
GLint infoLogLength;
ourGLchar *infoLog;
gl_GetProgramiv (program, GL_INFO_LOG_LENGTH, &infoLogLength);
infoLog = (ourGLchar*) malloc (infoLogLength);
gl_GetProgramInfoLog (program, infoLogLength, NULL, infoLog);
fprintf (stderr, "link log: %s\n", infoLog);
free (infoLog);
}
}
GLuint createProgram(GLuint vertexShader, GLuint fragmentShader)
{
GLuint program = gl_CreateProgram ();
if (vertexShader != 0) {
gl_AttachShader (program, vertexShader);
}
if (fragmentShader != 0) {
gl_AttachShader (program, fragmentShader);
}
linkAndCheck (program);
return program;
}
GLuint fgProjectionMatrixIndex;
GLuint fgColorIndex;
GLuint fgVertexIndex;
void initShader(void)
{
const GLsizei vertexShaderLines = sizeof(vertexShaderSource) / sizeof(ourGLchar*);
GLuint vertexShader =
compileShaderSource (GL_VERTEX_SHADER, vertexShaderLines, vertexShaderSource);
const GLsizei fragmentShaderLines = sizeof(fragmentShaderSource) / sizeof(ourGLchar*);
GLuint fragmentShader =
compileShaderSource (GL_FRAGMENT_SHADER, fragmentShaderLines, fragmentShaderSource);
GLuint program = createProgram (vertexShader, fragmentShader);
gl_UseProgram (program);
fgProjectionMatrixIndex = gl_GetUniformLocation(program, "fg_ProjectionMatrix");
fgColorIndex = gl_GetAttribLocation(program, "fg_Color");
gl_EnableVertexAttribArray (fgColorIndex);
fgVertexIndex = gl_GetAttribLocation(program, "fg_Vertex");
gl_EnableVertexAttribArray (fgVertexIndex);
checkError ("initShader");
}
void initRendering(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
checkError ("initRendering");
}
void init(void)
{
initExtensionEntries ();
initBuffer ();
initShader ();
initRendering ();
}
void dumpInfo(void)
{
printf ("Vendor: %s\n", glGetString (GL_VENDOR));
printf ("Renderer: %s\n", glGetString (GL_RENDERER));
printf ("Version: %s\n", glGetString (GL_VERSION));
printf ("GLSL: %s\n", glGetString (GL_SHADING_LANGUAGE_VERSION));
checkError ("dumpInfo");
}
const GLvoid *bufferObjectPtr (GLsizei index)
{
return (const GLvoid *) (((char *) NULL) + index);
}
GLfloat projectionMatrix[16];
void triangle(void)
{
gl_UniformMatrix4fv (fgProjectionMatrixIndex, 1, GL_FALSE, projectionMatrix);
gl_BindBuffer (GL_ARRAY_BUFFER, vertexBufferName);
gl_VertexAttribPointer (fgColorIndex, numColorComponents, GL_FLOAT, GL_FALSE,
stride, bufferObjectPtr (0));
gl_VertexAttribPointer (fgVertexIndex, numVertexComponents, GL_FLOAT, GL_FALSE,
stride, bufferObjectPtr (sizeof(GLfloat) * numColorComponents));
glDrawArrays(GL_TRIANGLES, 0, numElements);
checkError ("triangle");
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
triangle ();
glFlush ();
checkError ("display");
}
void loadOrthof(GLfloat *m, GLfloat l, GLfloat r, GLfloat b, GLfloat t,
GLfloat n, GLfloat f)
{
m[ 0] = 2.0f / (r - l);
m[ 1] = 0.0f;
m[ 2] = 0.0f;
m[ 3] = 0.0f;
m[ 4] = 0.0f;
m[ 5] = 2.0f / (t - b);
m[ 6] = 0.0f;
m[ 7] = 0.0f;
m[ 8] = 0.0f;
m[ 9] = 0.0f;
m[10] = -2.0f / (f - n);
m[11] = 0.0f;
m[12] = -(r + l) / (r - l);
m[13] = -(t + b) / (t - b);
m[14] = -(f + n) / (f - n);
m[15] = 1.0f;
}
void loadOrtho2Df(GLfloat *m, GLfloat l, GLfloat r, GLfloat b, GLfloat t)
{
loadOrthof (m, l, r, b, t, -1.0f, 1.0f);
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
if (w <= h) {
loadOrtho2Df (projectionMatrix, 0.0f, 30.0f, 0.0f, 30.0f * (GLfloat) h/(GLfloat) w);
} else {
loadOrtho2Df (projectionMatrix, 0.0f, 30.0f * (GLfloat) w/(GLfloat) h, 0.0f, 30.0f);
}
checkError ("reshape");
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}
void samplemenu(int menuID)
{}
int main(int argc, char** argv)
{
int menuA;
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
/* add command line argument "classic" for a pre-3.x context */
if ((argc != 2) || (strcmp (argv[1], "classic") != 0)) {
glutInitContextVersion (3, 1);
glutInitContextFlags (GLUT_FORWARD_COMPATIBLE | GLUT_DEBUG);
}
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
dumpInfo ();
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc (keyboard);
/* Add a menu. They have their own context and should thus work with forward compatible main windows too. */
menuA = glutCreateMenu(samplemenu);
glutAddMenuEntry("Sub menu A1 (01)",1);
glutAddMenuEntry("Sub menu A2 (02)",2);
glutAddMenuEntry("Sub menu A3 (03)",3);
glutSetMenu(menuA);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMainLoop();
return 0;
}

View File

@ -0,0 +1,177 @@
/* Spaceball demo
*
* Written by John Tsiombikas <nuclear@member.fsf.org>
* (converted from the libspnav cube example)
*
* Use the spaceball to move and rotate the colored cube.
* Pressing any button will reset the cube at its original location.
*
* Press escape or q to exit.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/freeglut.h>
#include "vmath.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950
#endif
void draw_cube(void);
/* callbacks */
void disp(void);
void reshape(int x, int y);
void keyb(unsigned char key, int x, int y);
void sbmot(int x, int y, int z); /* spaceball translation */
void sbrot(int x, int y, int z); /* spaceball rotation */
void sbbut(int bn, int state); /* spaceball button */
vec3_t pos = {0, 0, -6};
quat_t rot = {0, 0, 0, 1};
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("spaceball demo");
glutDisplayFunc(disp);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyb);
glutSpaceballMotionFunc(sbmot);
glutSpaceballRotateFunc(sbrot);
glutSpaceballButtonFunc(sbbut);
glEnable(GL_CULL_FACE);
glutMainLoop();
return 0;
}
void disp(void)
{
mat4_t xform;
quat_to_mat(xform, rot);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(pos.x, pos.y, pos.z);
glMultMatrixf((float*)xform);
draw_cube();
glutSwapBuffers();
}
void draw_cube(void)
{
glBegin(GL_QUADS);
/* face +Z */
glNormal3f(0, 0, 1);
glColor3f(1, 0, 0);
glVertex3f(-1, -1, 1);
glVertex3f(1, -1, 1);
glVertex3f(1, 1, 1);
glVertex3f(-1, 1, 1);
/* face +X */
glNormal3f(1, 0, 0);
glColor3f(0, 1, 0);
glVertex3f(1, -1, 1);
glVertex3f(1, -1, -1);
glVertex3f(1, 1, -1);
glVertex3f(1, 1, 1);
/* face -Z */
glNormal3f(0, 0, -1);
glColor3f(0, 0, 1);
glVertex3f(1, -1, -1);
glVertex3f(-1, -1, -1);
glVertex3f(-1, 1, -1);
glVertex3f(1, 1, -1);
/* face -X */
glNormal3f(-1, 0, 0);
glColor3f(1, 1, 0);
glVertex3f(-1, -1, -1);
glVertex3f(-1, -1, 1);
glVertex3f(-1, 1, 1);
glVertex3f(-1, 1, -1);
/* face +Y */
glNormal3f(0, 1, 0);
glColor3f(0, 1, 1);
glVertex3f(-1, 1, 1);
glVertex3f(1, 1, 1);
glVertex3f(1, 1, -1);
glVertex3f(-1, 1, -1);
/* face -Y */
glNormal3f(0, -1, 0);
glColor3f(1, 0, 1);
glVertex3f(-1, -1, -1);
glVertex3f(1, -1, -1);
glVertex3f(1, -1, 1);
glVertex3f(-1, -1, 1);
glEnd();
}
/* 45deg fov */
#define FOV (M_PI / 4.0)
void reshape(int x, int y)
{
float aspect = (float)x / (float)y;
float halfy = (float)tan(FOV / 2.0);
float halfx = halfy * aspect;
glViewport(0, 0, x, y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-halfx, halfx, -halfy, halfy, 1.0, 1000.0);
}
void keyb(unsigned char key, int x, int y)
{
switch(key) {
case 'q':
case 'Q':
case 27:
exit(0);
case ' ':
/* reset initial view */
pos = v3_cons(0, 0, -6);
rot = quat_cons(1, 0, 0, 0);
glutPostRedisplay();
default:
break;
}
}
void sbmot(int x, int y, int z)
{
pos.x += x * 0.001f;
pos.y += y * 0.001f;
pos.z -= z * 0.001f;
glutPostRedisplay();
}
void sbrot(int x, int y, int z)
{
float axis_len = (float)sqrt(x * x + y * y + z * z);
rot = quat_rotate(rot, axis_len * 0.001f, -x / axis_len, -y / axis_len, z / axis_len);
glutPostRedisplay();
}
void sbbut(int bn, int state)
{
if(state == GLUT_DOWN) {
pos = v3_cons(0, 0, -6);
rot = quat_cons(1, 0, 0, 0);
glutPostRedisplay();
}
}

View File

@ -0,0 +1,16 @@
#include <math.h>
#include "vmath.h"
quat_t quat_rotate(quat_t q, float angle, float x, float y, float z)
{
quat_t rq;
float half_angle = angle * 0.5f;
float sin_half = (float)sin(half_angle);
rq.w = (float)cos(half_angle);
rq.x = x * sin_half;
rq.y = y * sin_half;
rq.z = z * sin_half;
return quat_mul(q, rq);
}

View File

@ -0,0 +1,38 @@
#ifndef VMATH_H_
#define VMATH_H_
#if defined(WIN32)
#define INLINE
#else
#define INLINE inline
#endif
typedef struct { float x, y, z; } vec3_t;
typedef struct { float x, y, z, w; } vec4_t;
typedef vec4_t quat_t;
typedef float mat4_t[4][4];
/* vector functions */
static INLINE vec3_t v3_cons(float x, float y, float z);
static INLINE float v3_dot(vec3_t v1, vec3_t v2);
/* quaternion functions */
static INLINE quat_t quat_cons(float s, float x, float y, float z);
static INLINE vec3_t quat_vec(quat_t q);
static INLINE quat_t quat_mul(quat_t q1, quat_t q2);
static INLINE void quat_to_mat(mat4_t res, quat_t q);
quat_t quat_rotate(quat_t q, float angle, float x, float y, float z);
/* matrix functions */
static INLINE void m4_cons(mat4_t m,
float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44);
#include "vmath.inl"
#endif /* VMATH_H_ */

View File

@ -0,0 +1,68 @@
/* vector functions */
static INLINE vec3_t v3_cons(float x, float y, float z)
{
vec3_t res;
res.x = x;
res.y = y;
res.z = z;
return res;
}
static INLINE vec3_t quat_vec(quat_t q)
{
vec3_t v;
v.x = q.x;
v.y = q.y;
v.z = q.z;
return v;
}
static INLINE float v3_dot(vec3_t v1, vec3_t v2)
{
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
/* quaternion functions */
static INLINE quat_t quat_cons(float s, float x, float y, float z)
{
quat_t q;
q.x = x;
q.y = y;
q.z = z;
q.w = s;
return q;
}
static INLINE quat_t quat_mul(quat_t q1, quat_t q2)
{
quat_t res;
vec3_t v1 = quat_vec(q1);
vec3_t v2 = quat_vec(q2);
res.w = q1.w * q2.w - v3_dot(v1, v2);
res.x = v2.x * q1.w + v1.x * q2.w + (v1.y * v2.z - v1.z * v2.y);
res.y = v2.y * q1.w + v1.y * q2.w + (v1.z * v2.x - v1.x * v2.z);
res.z = v2.z * q1.w + v1.z * q2.w + (v1.x * v2.y - v1.y * v2.x);
return res;
}
static INLINE void quat_to_mat(mat4_t res, quat_t q)
{
m4_cons(res, 1.0f - 2.0f * q.y*q.y - 2.0f * q.z*q.z, 2.0f * q.x * q.y + 2.0f * q.w * q.z, 2.0f * q.z * q.x - 2.0f * q.w * q.y, 0,
2.0f * q.x * q.y - 2.0f * q.w * q.z, 1.0f - 2.0f * q.x*q.x - 2.0f * q.z*q.z, 2.0f * q.y * q.z + 2.0f * q.w * q.x, 0,
2.0f * q.z * q.x + 2.0f * q.w * q.y, 2.0f * q.y * q.z - 2.0f * q.w * q.x, 1.0f - 2.0f * q.x*q.x - 2.0f * q.y*q.y, 0,
0, 0, 0, 1);
}
/* matrix functions */
static INLINE void m4_cons(mat4_t m,
float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44)
{
m[0][0] = m11; m[1][0] = m12; m[2][0] = m13; m[3][0] = m14;
m[0][1] = m21; m[1][1] = m22; m[2][1] = m23; m[3][1] = m24;
m[0][2] = m31; m[1][2] = m32; m[2][2] = m33; m[3][2] = m34;
m[0][3] = m41; m[1][3] = m42; m[2][3] = m43; m[3][3] = m44;
}

235
progs/demos/subwin/subwin.c Normal file
View File

@ -0,0 +1,235 @@
/*! \file subwin.c
\ingroup demos
This program is a test harness for the subwindows
in OpenGLUT. Based Originally on shape.c demo.
\author Written by Evan Felix February 2011
\author Portions Copyright (C) 2004, the OpenGLUT project contributors. <br>
OpenGLUT branched from freeglut in February, 2004.
\image html openglut_subwin.png OpenGLUT Sub Window Demonstration
\include demos/subwin/subwin.c
*/
#include <GL/freeglut.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _MSC_VER
/* DUMP MEMORY LEAKS */
#include <crtdbg.h>
#endif
#define MAXSTR 16
char **strings;
int mainwin;
/*!
Does printf()-like work using freeglut/OpenGLUT
glutBitmapString(). Uses a fixed font. Prints
at the indicated row/column position.
Limitation: Cannot address pixels.
Limitation: Renders in screen coords, not model coords.
*/
static void shapesPrintf (int row, int col, const char *fmt, ...)
{
static char buf[256];
int viewport[4];
void *font = GLUT_BITMAP_9_BY_15;
va_list args;
va_start(args, fmt);
#if defined(WIN32) && !defined(__CYGWIN__)
(void) _vsnprintf (buf, sizeof(buf), fmt, args);
#else
(void) vsnprintf (buf, sizeof(buf), fmt, args);
#endif
va_end(args);
glGetIntegerv(GL_VIEWPORT,viewport);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0,viewport[2],0,viewport[3],-1,1);
glRasterPos2i
(
glutBitmapWidth(font, ' ') * col,
- glutBitmapHeight(font) * (row+2) + viewport[3]
);
glutBitmapString (font, (unsigned char*)buf);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
/* GLUT callback Handlers */
static void
resize(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/*gluOrtho2D(0, width, 0, height);*/
glMatrixMode(GL_MODELVIEW);
glLoadIdentity() ;
}
static void display(void)
{
int win = glutGetWindow();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3d(1,0,0);
glDisable(GL_LIGHTING);
glColor3d(0.1,0.1,0.4);
if (win == mainwin)
{
shapesPrintf (2, 3, "Move The mouse into different windows");
shapesPrintf (3, 3, "pressing keys will add to the string");
shapesPrintf (5, 3, "Window: %d", win);
shapesPrintf (6, 3, "String: %s", strings[win]);
}
else
{
shapesPrintf (1, 3, "Window: %d", win);
shapesPrintf (2, 3, "String: %s", strings[win]);
}
glutSwapBuffers();
}
static void
key(unsigned char key, int x, int y)
{
char *s,str[2];
int win = glutGetWindow();
switch (key)
{
case 27 :
case 'Q':
case 'q': glutLeaveMainLoop () ; break;
default:
s=strings[win];
if (strlen(s)+1>MAXSTR) {
s[0]=0;
}
str[0]=key;
str[1]=0;
strcat(s,str);
break;
}
glutPostRedisplay();
}
static void special (int key, int x, int y)
{
switch (key)
{
default:
break;
}
glutPostRedisplay();
}
static void
entry(int state)
{
int win = glutGetWindow();
printf("Win: %d, state: %d\n",win,state);
}
/* Program entry point */
int
main(int argc, char *argv[])
{
int winmax,sw1,sw2,sw2sw,i;
glutInitWindowSize(640,480);
glutInitWindowPosition(40,40);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
glutCreateWindow("FreeGLUT Sub Windows");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutSpecialFunc(special);
glutEntryFunc(entry);
glutSetOption ( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION ) ;
glClearColor(1,1,1,1);
mainwin = glutGetWindow();
winmax=mainwin;
sw1=glutCreateSubWindow(mainwin,4,240,314,236);
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutSpecialFunc(special);
glutEntryFunc(entry);
glClearColor(0.7f,0.7f,0.7f,1);
winmax = sw1 > winmax ? sw1 : winmax;
sw2=glutCreateSubWindow(mainwin,322,240,314,236);
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutSpecialFunc(special);
glutEntryFunc(entry);
glClearColor(0.7f,0.7f,0.7f,1);
winmax = sw2 > winmax ? sw2 : winmax;
sw2sw=glutCreateSubWindow(sw2,10,128,294,98);
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutSpecialFunc(special);
glutEntryFunc(entry);
glClearColor(0.4f,0.4f,0.4f,1);
winmax = sw2sw > winmax ? sw2sw : winmax;
strings = malloc(sizeof(char *)*(winmax+1));
for (i=0;i<winmax+1;i++) {
strings[i] = malloc(sizeof(char)*MAXSTR+1);
strings[i][0]=0;
}
glutMainLoop();
#ifdef _MSC_VER
/* DUMP MEMORY LEAK INFORMATION */
_CrtDumpMemoryLeaks () ;
#endif
return EXIT_SUCCESS;
}

144
progs/demos/timer/timer.c Normal file
View File

@ -0,0 +1,144 @@
/* Timer demo
*
* Written by John Tsiombikas <nuclear@member.fsf.org>
*
* Demonstrate the use of glutTimerFunc, by changing the color of the
* framebuffer every (approximately) 1 sec.
*/
#include <stdio.h>
#include <GL/glut.h>
void disp(void);
void timer_func(int unused);
/* color index will be advanced every time the timer expires */
int cidx = 0;
int pcidx = 2;
float color[][3] = {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1},
{1, 1, 0},
{0, 1, 1},
{1, 0, 1}
};
int timerInts[] = {
250,
500,
1000
};
int timerSurroundInt = 1000, timerCenterInt = 1000;
/* menu IDs, creation/update funcs and callback */
int menuID, subMenuSurround, subMenuCenter;
void createMenuEntries(int which)
{
int i;
for (i = 0; i < sizeof(timerInts) / sizeof(*timerInts); i++)
{
char temp[10] = {'\0'};
/* flag current value */
if ((which == 1 ? timerSurroundInt : timerCenterInt) == timerInts[i])
temp[0] = '+';
else
temp[0] = '-';
sprintf(temp + 1, " %4d ms", timerInts[i]);
glutAddMenuEntry(temp, timerInts[i]);
}
}
void updateMenuEntries(int which)
{
int i;
for (i = 0; i < sizeof(timerInts) / sizeof(*timerInts); i++)
{
char temp[10] = { '\0' };
/* flag current value */
if ((which == 1 ? timerSurroundInt : timerCenterInt) == timerInts[i])
temp[0] = '+';
else
temp[0] = '-';
sprintf(temp + 1, " %4d ms", timerInts[i]);
glutChangeToMenuEntry(i+1, temp, timerInts[i]);
}
}
void MenuSurround(int timerInt)
{
timerSurroundInt = timerInt;
glutSetMenu(subMenuSurround);
updateMenuEntries(1);
}
void MenuCenter(int timerInt)
{
timerCenterInt = timerInt;
glutSetMenu(subMenuCenter);
updateMenuEntries(2);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(128, 128);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("timer test");
glutDisplayFunc(disp);
/* get timer started, its reset in the timer function itself */
glutTimerFunc(1000, timer_func, 1);
glutTimerFunc(500, timer_func, 2);
/* menus for setting timing */
subMenuSurround = glutCreateMenu(MenuSurround);
createMenuEntries(1);
subMenuCenter = glutCreateMenu(MenuCenter);
createMenuEntries(2);
menuID = glutCreateMenu(MenuSurround); /* doesn't matter, no clickable entries in this menu */
glutAddSubMenu("Center", subMenuCenter);
glutAddSubMenu("Surround", subMenuSurround);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMainLoop();
return 0;
}
void disp(void)
{
glClearColor(color[cidx][0], color[cidx][1], color[cidx][2], 1);
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(10.f);
glColor3f(color[pcidx][0], color[pcidx][1], color[pcidx][2]);
glBegin(GL_POINTS);
glVertex2i(0,0);
glEnd();
glutSwapBuffers();
}
void timer_func(int which)
{
/* advance the color index and trigger a redisplay */
switch (which)
{
case 1:
cidx = (cidx + 1) % (sizeof color / sizeof *color);
break;
case 2:
pcidx = (pcidx + 1) % (sizeof color / sizeof *color);
break;
}
glutPostRedisplay();
/* (re)set the timer callback and ask glut to call it in x ms */
glutTimerFunc(which == 1 ? timerSurroundInt:timerCenterInt, timer_func, which);
}

View File

@ -0,0 +1,174 @@
/* Timer (callback) demo
*
* Written by John Tsiombikas <nuclear@member.fsf.org>
* Modified by Vincent Simonetti
*
* A modification of the timer sample, but with this
* offering a use of the user-data callback.
*/
#include <stdio.h>
#include <GL/freeglut.h>
struct display_index_s
{
/* color index will be advanced every time the timer expires */
int surround_color_index;
int center_color_index;
};
typedef struct display_index_s display_index_t;
struct timer_state_s
{
int* color_index_ptr;
int* timer_time_ptr;
};
typedef struct timer_state_s timer_state_t;
struct menu_state_s
{
int* timer_time_ptr;
int menu_id;
};
typedef struct menu_state_s menu_state_t;
void disp(void* uptr);
void timer_func(int which, void* uptr);
const float color[][3] = {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1},
{1, 1, 0},
{0, 1, 1},
{1, 0, 1}
};
const int timerInts[] = {
250,
500,
1000
};
void createMenuEntries(menu_state_t* menuState)
{
int i;
for (i = 0; i < sizeof(timerInts) / sizeof(*timerInts); i++)
{
char temp[10] = {'\0'};
/* flag current value */
if ((*menuState->timer_time_ptr) == timerInts[i])
temp[0] = '+';
else
temp[0] = '-';
sprintf(temp + 1, " %4d ms", timerInts[i]);
glutAddMenuEntry(temp, timerInts[i]);
}
}
void updateMenuEntries(menu_state_t* menuState)
{
int i;
for (i = 0; i < sizeof(timerInts) / sizeof(*timerInts); i++)
{
char temp[10] = { '\0' };
/* flag current value */
if ((*menuState->timer_time_ptr) == timerInts[i])
temp[0] = '+';
else
temp[0] = '-';
sprintf(temp + 1, " %4d ms", timerInts[i]);
glutChangeToMenuEntry(i+1, temp, timerInts[i]);
}
}
void MenuHandler(int timerInt, void* user_ptr)
{
menu_state_t* menuState;
if (!user_ptr)
{
/* In case main menu is selected somehow */
return;
}
menuState = (menu_state_t*)user_ptr;
*menuState->timer_time_ptr = timerInt;
glutSetMenu(menuState->menu_id);
updateMenuEntries(menuState);
}
int main(int argc, char **argv)
{
int timerSurroundInt = 1000, timerCenterInt = 500;
display_index_t displayIndex = { 0, 2 };
timer_state_t surroundTimerState = { &displayIndex.surround_color_index, &timerSurroundInt };
timer_state_t centerTimerState = { &displayIndex.center_color_index, &timerCenterInt };
menu_state_t surroundMenuState = { &timerSurroundInt, 0 };
menu_state_t centerMenuState = { &timerCenterInt, 0 };
glutInit(&argc, argv);
glutInitWindowSize(128, 128);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutCreateWindow("timer test");
glutDisplayFuncUcall(disp, &displayIndex);
/* get timer started, its reset in the timer function itself */
glutTimerFuncUcall(timerSurroundInt, timer_func, 1, &surroundTimerState);
glutTimerFuncUcall(timerCenterInt, timer_func, 2, &centerTimerState);
/* menus for setting timing */
surroundMenuState.menu_id = glutCreateMenuUcall(MenuHandler, &surroundMenuState);
createMenuEntries(&surroundMenuState);
centerMenuState.menu_id = glutCreateMenuUcall(MenuHandler, &centerMenuState);
createMenuEntries(&centerMenuState);
glutCreateMenuUcall(MenuHandler, NULL); /* doesn't matter, no clickable entries in this menu */
glutAddSubMenu("Center", centerMenuState.menu_id);
glutAddSubMenu("Surround", surroundMenuState.menu_id);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMainLoop();
return 0;
}
void disp(void* user_ptr)
{
const display_index_t* displayIndex;
int cidx, pcidx;
displayIndex = (display_index_t*)user_ptr;
cidx = displayIndex->surround_color_index;
glClearColor(color[cidx][0], color[cidx][1], color[cidx][2], 1);
glClear(GL_COLOR_BUFFER_BIT);
pcidx = displayIndex->center_color_index;
glPointSize(10.f);
glColor3f(color[pcidx][0], color[pcidx][1], color[pcidx][2]);
glBegin(GL_POINTS);
glVertex2i(0,0);
glEnd();
glutSwapBuffers();
}
void timer_func(int which, void* user_ptr)
{
const timer_state_t* timerState;
timerState = (timer_state_t*)user_ptr;
/* advance the color index and trigger a redisplay */
*timerState->color_index_ptr = (*timerState->color_index_ptr + 1) % (sizeof color / sizeof *color);
glutPostRedisplay();
/* (re)set the timer callback and ask glut to call it in x ms */
glutTimerFuncUcall(*timerState->timer_time_ptr, timer_func, which, user_ptr);
}

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="freeglut.test.gles1"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<uses-feature android:glEsVersion="0x00010001"></uses-feature>
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="true"
android:debuggable="true"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of or .so -->
<meta-data android:name="android.app.lib_name"
android:value="test-shapes-gles1" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->

View File

@ -0,0 +1,42 @@
cmake_minimum_required(VERSION 2.6)
project(test-shapes-gles1)
IF(CMAKE_COMPILER_IS_GNUCC)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
IF(!ANDROID)
# not setting -ansi as EGL/KHR headers doesn't support it
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ansi")
ENDIF()
ENDIF(CMAKE_COMPILER_IS_GNUCC)
# FreeGLUT
include(FindPkgConfig)
pkg_check_modules(freeglut REQUIRED freeglut-gles>=3.0.0)
if(freeglut_FOUND)
include_directories(${freeglut_STATIC_INCLUDE_DIRS})
link_directories(${freeglut_STATIC_LIBRARY_DIRS})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${freeglut_STATIC_CFLAGS_OTHER}")
add_definitions(${freeglut_STATIC_CFLAGS_OTHER})
endif()
if(ANDROID)
add_library(test-shapes-gles1 SHARED test-shapes-gles1.c)
add_custom_target(apk ALL
DEPENDS test-shapes-gles1
COMMAND ant clean || true
COMMAND rm -rf libs/ src/ res/ bin/ gen/
COMMAND mkdir -p libs/armeabi/ src/ res/values/
COMMAND cp -a ${PROJECT_SOURCE_DIR}/AndroidManifest.xml ${PROJECT_BINARY_DIR}
COMMAND cp -a $<TARGET_FILE:test-shapes-gles1> libs/armeabi/
COMMAND echo '<?xml version="1.0" encoding="utf-8"?><resources><string name="app_name">FG_GLES1 test</string></resources>'
> res/values/strings.xml
COMMAND android update project --name cmake-apk --path . --target "android-10"
COMMAND ant debug
COMMAND ant installd
COMMAND adb shell am start -a android.intenon.MAIN -n freeglut.test.gles1/android.app.NativeActivity
)
# Note: at least one resource and an empty src/ dir is necessary for ant...
else()
add_executable(test-shapes-gles1 test-shapes-gles1.c)
endif()
target_link_libraries(test-shapes-gles1 ${freeglut_STATIC_LIBRARIES})

View File

@ -0,0 +1 @@
../../android_toolchain.cmake

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.wikibooks.OpenGL"
android:versionCode="1"
android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="9" />
<uses-feature android:glEsVersion="0x00020000"></uses-feature>
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="true"
android:icon="@drawable/icon"
android:debuggable="true"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden">
<!-- Tell NativeActivity the name of or .so -->
<meta-data android:name="android.app.lib_name"
android:value="native-activity" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<!-- END_INCLUDE(manifest) -->

View File

@ -0,0 +1,14 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := native-activity
LOCAL_SRC_FILES :=
LOCAL_CPPFLAGS := -I/usr/src/glm
LOCAL_CXXFLAGS := -gstabs+
LOCAL_LDLIBS := -llog -landroid -lGLESv2 -lEGL
LOCAL_STATIC_LIBRARIES := freeglut
include $(BUILD_SHARED_LIBRARY)
$(call import-module,freeglut)

View File

@ -0,0 +1,2 @@
APP_PLATFORM := android-9
APP_STL := gnustl_static

View File

@ -0,0 +1,341 @@
/*! \file shapes.c
\ingroup demos
This program is a test harness for the various shapes
in OpenGLUT. It may also be useful to see which
parameters control what behavior in the OpenGLUT
objects.
Spinning wireframe and solid-shaded shapes are
displayed. Some parameters can be adjusted.
Keys:
- <tt>Esc &nbsp;</tt> Quit
- <tt>q Q &nbsp;</tt> Quit
- <tt>i I &nbsp;</tt> Show info
- <tt>p P &nbsp;</tt> Toggle perspective or orthographic projection
- <tt>= + &nbsp;</tt> Increase \a slices
- <tt>- _ &nbsp;</tt> Decreate \a slices
- <tt>, < &nbsp;</tt> Decreate \a stacks
- <tt>. > &nbsp;</tt> Increase \a stacks
- <tt>9 ( &nbsp;</tt> Decreate \a depth (Sierpinski Sponge)
- <tt>0 ) &nbsp;</tt> Increase \a depth (Sierpinski Sponge)
- <tt>up&nbsp; &nbsp;</tt> Increase "outer radius"
- <tt>down&nbsp;</tt> Decrease "outer radius"
- <tt>left&nbsp;</tt> Decrease "inner radius"
- <tt>right</tt> Increase "inner radius"
- <tt>PgUp&nbsp;</tt> Next shape-drawing function
- <tt>PgDn&nbsp;</tt> Prev shape-drawing function
\author Written by Nigel Stewart November 2003
\author Portions Copyright (C) 2004, the OpenGLUT project contributors. <br>
OpenGLUT branched from freeglut in February, 2004.
\image html openglut_shapes.png OpenGLUT Geometric Shapes Demonstration
\include demos/shapes/shapes.c
*/
#include <GL/freeglut.h>
#include <GL/freeglut_ext.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
/* DUMP MEMORY LEAKS */
#include <crtdbg.h>
#endif
/*
* This macro is only intended to be used on arrays, of course.
*/
#define NUMBEROF(x) ((sizeof(x))/(sizeof(x[0])))
#define glRotated glRotatef
#define glTranslated glTranslatef
/*
* These global variables control which object is drawn,
* and how it is drawn. No object uses all of these
* variables.
*/
static int function_index;
static int slices = 16;
static int stacks = 16;
static double irad = .25;
static double orad = 1.0; /* doubles as size for objects other than Torus */
static int depth = 4;
static double offset[ 3 ] = { 0, 0, 0 };
static GLboolean show_info = GL_TRUE;
static float ar;
static GLboolean persProject = GL_TRUE;
static GLboolean animateXRot = GL_FALSE;
/*
* These one-liners draw particular objects, fetching appropriate
* information from the above globals. They are just thin wrappers
* for the FreeGLUT objects.
*/
static void drawSolidTetrahedron(void) { glutSolidTetrahedron (); }
static void drawWireTetrahedron(void) { glutWireTetrahedron (); }
static void drawSolidCube(void) { glutSolidCube(orad); } /* orad doubles as size input */
static void drawWireCube(void) { glutWireCube(orad); } /* orad doubles as size input */
static void drawSolidOctahedron(void) { glutSolidOctahedron (); }
static void drawWireOctahedron(void) { glutWireOctahedron (); }
static void drawSolidDodecahedron(void) { glutSolidDodecahedron (); }
static void drawWireDodecahedron(void) { glutWireDodecahedron (); }
static void drawSolidRhombicDodecahedron(void) { glutSolidRhombicDodecahedron (); }
static void drawWireRhombicDodecahedron(void) { glutWireRhombicDodecahedron (); }
static void drawSolidIcosahedron(void) { glutSolidIcosahedron (); }
static void drawWireIcosahedron(void) { glutWireIcosahedron (); }
static void drawSolidSierpinskiSponge(void) { glutSolidSierpinskiSponge (depth, offset, orad);} /* orad doubles as size input */
static void drawWireSierpinskiSponge(void) { glutWireSierpinskiSponge (depth, offset, orad); } /* orad doubles as size input */
static void drawSolidTorus(void) { glutSolidTorus(irad,orad,slices,stacks); }
static void drawWireTorus(void) { glutWireTorus (irad,orad,slices,stacks); }
static void drawSolidSphere(void) { glutSolidSphere(orad,slices,stacks); } /* orad doubles as size input */
static void drawWireSphere(void) { glutWireSphere(orad,slices,stacks); } /* orad doubles as size input */
static void drawSolidCone(void) { glutSolidCone(orad,orad,slices,stacks); } /* orad doubles as size input */
static void drawWireCone(void) { glutWireCone(orad,orad,slices,stacks); } /* orad doubles as size input */
static void drawSolidCylinder(void) { glutSolidCylinder(orad,orad,slices,stacks); } /* orad doubles as size input */
static void drawWireCylinder(void) { glutWireCylinder(orad,orad,slices,stacks); } /* orad doubles as size input */
static void drawSolidTeapot(void)
{ glFrontFace(GL_CW); glutSolidTeapot(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
static void drawWireTeapot(void)
{ glFrontFace(GL_CW); glutWireTeapot(orad); glFrontFace(GL_CCW); /* orad doubles as size input */}
/*
* This structure defines an entry in our function-table.
*/
typedef struct
{
const char * const name;
void (*solid) (void);
void (*wire) (void);
} entry;
#define ENTRY(e) {#e, drawSolid##e, drawWire##e}
static const entry table [] =
{
ENTRY (Tetrahedron),
ENTRY (Cube),
ENTRY (Octahedron),
ENTRY (Dodecahedron),
ENTRY (RhombicDodecahedron),
ENTRY (Icosahedron),
ENTRY (SierpinskiSponge),
ENTRY (Teapot),
ENTRY (Torus),
ENTRY (Sphere),
ENTRY (Cone),
ENTRY (Cylinder),
/* ENTRY (Cuboctahedron) */
};
#undef ENTRY
/*!
Does printf()-like work using freeglut
glutBitmapString(). Uses a fixed font. Prints
at the indicated row/column position.
Limitation: Cannot address pixels.
Limitation: Renders in screen coords, not model coords.
*/
static void shapesPrintf (int row, int col, const char *fmt, ...)
{
}
/* GLUT callback Handlers */
static void
resize(int width, int height)
{
ar = (float) width / (float) height;
glViewport(0, 0, width, height);
}
static void display(void)
{
const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
const double a = t*90.0;
const double b = (animateXRot?t:1)*60.0;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustumf(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_LIGHTING);
glColor4f(1,0,0,1);
glPushMatrix();
glTranslated(0,1.2,-6);
glRotated(b,1,0,0);
glRotated(a,0,0,1);
table [function_index].solid ();
glPopMatrix();
glPushMatrix();
glTranslated(0,-1.2,-6);
glRotated(b,1,0,0);
glRotated(a,0,0,1);
table [function_index].wire ();
glPopMatrix();
glDisable(GL_LIGHTING);
glColor4f(0.1,0.1,0.4,1.0);
glutSwapBuffers();
}
static void
key(unsigned char key, int x, int y)
{
switch (key)
{
case 27 :
case 'Q':
case 'q': glutLeaveMainLoop () ; break;
case 'I':
case 'i': show_info = ( show_info == GL_TRUE ) ? GL_FALSE : GL_TRUE; break;
case '=':
case '+': slices++; printf("%d,%d\n", slices, stacks); break;
case '-':
case '_': if( slices > -1 ) slices--; break;
case ',':
case '<': if( stacks > -1 ) stacks--; break;
case '.':
case '>': stacks++; break;
case '9':
case '(': if( depth > -1 ) depth--; break;
case '0':
case ')': ++depth; break;
case 'P':
case 'p': persProject=!persProject; break;
case 'R':
case 'r': animateXRot=!animateXRot; break;
default:
break;
}
glutPostRedisplay();
}
static void special (int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_PAGE_UP: ++function_index; break;
case GLUT_KEY_PAGE_DOWN: --function_index; break;
case GLUT_KEY_UP: orad *= 2; break;
case GLUT_KEY_DOWN: orad /= 2; break;
case GLUT_KEY_RIGHT: irad *= 2; break;
case GLUT_KEY_LEFT: irad /= 2; break;
default:
break;
}
if (0 > function_index)
function_index = NUMBEROF (table) - 1;
if (NUMBEROF (table) <= ( unsigned )function_index)
function_index = 0;
}
static void
idle(void)
{
glutPostRedisplay();
}
static void
onMouseClick(int button, int state, int x, int y) {
if (state == GLUT_DOWN)
special(GLUT_KEY_PAGE_UP, 0, 0);
}
const GLfloat light_ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
const GLfloat mat_ambient[] = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };
/* Program entry point */
void init_context() {
printf("init_context\n"); fflush(stdout);
glClearColor(1,1,1,1);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
}
int
main(int argc, char *argv[])
{
glutInitWindowSize(640,480);
glutInitWindowPosition(40,40);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
glutCreateWindow("FreeGLUT Shapes");
glutReshapeFunc(resize);
glutDisplayFunc(display);
glutKeyboardFunc(key);
glutSpecialFunc(special);
glutIdleFunc(idle);
glutMouseFunc(onMouseClick);
glutInitContextFunc(init_context);
glutSetOption ( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION ) ;
glutMainLoop();
#ifdef _MSC_VER
/* DUMP MEMORY LEAK INFORMATION */
_CrtDumpMemoryLeaks () ;
#endif
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,42 @@
/*
* fg_cursor_android.c
*
* The Windows-specific mouse cursor related stuff.
*
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "../fg_internal.h"
void fgPlatformSetCursor ( SFG_Window *window, int cursorID )
{
/* No-op: no visible cursor on touchscreens */
}
void fgPlatformWarpPointer ( int x, int y )
{
/* Even if there's no pointer on touchscreen, keep track of the
last position, e.g. for menus */
SFG_Window* window = fgStructure.CurrentWindow;
window->State.MouseX = x;
window->State.MouseY = y;
/* TODO: this should simulate a fake motion event */
}

View File

@ -0,0 +1,48 @@
/*
* fg_ext_android.c
*
* Functions related to OpenGL extensions.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Copied for Platform code by Evan Felix <karcaw at gmail.com>
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "../fg_internal.h"
GLUTproc fgPlatformGetGLUTProcAddress( const char* procName )
{
/* optimization: quick initial check */
if( strncmp( procName, "glut", 4 ) != 0 )
return NULL;
#define CHECK_NAME(x) if( strcmp( procName, #x ) == 0) return (GLUTproc)x;
CHECK_NAME(glutJoystickFunc);
CHECK_NAME(glutForceJoystickFunc);
CHECK_NAME(glutGameModeString);
CHECK_NAME(glutEnterGameMode);
CHECK_NAME(glutLeaveGameMode);
CHECK_NAME(glutGameModeGet);
#undef CHECK_NAME
return NULL;
}

View File

@ -0,0 +1,57 @@
/*
* fg_gamemode_x11.c
*
* The game mode handling code.
*
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "fg_internal.h"
/*
* Changes the current display mode to match user's settings
*/
GLboolean fgPlatformChangeDisplayMode( GLboolean haveToTest )
{
fprintf(stderr, "fgPlatformChangeDisplayMode: STUB\n");
return GL_FALSE;
}
void fgPlatformEnterGameMode( void )
{
fprintf(stderr, "fgPlatformEnterGameMode: STUB\n");
}
void fgPlatformRememberState( void )
{
fprintf(stderr, "fgPlatformRememberState: STUB\n");
}
void fgPlatformRestoreState( void )
{
fprintf(stderr, "fgPlatformRestoreState: STUB\n");
}
void fgPlatformLeaveGameMode( void )
{
fprintf(stderr, "fgPlatformLeaveGameMode: STUB\n");
}

View File

@ -0,0 +1,54 @@
/*
* fg_init_android.c
*
* Various freeglut initialization functions.
*
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "fg_internal.h"
#include "fg_init.h"
#include "egl/fg_init_egl.h"
void fgPlatformInitialize()
{
fghPlatformInitializeEGL();
/* Get start time */
fgState.Time = fgSystemTime();
fgState.Initialised = GL_TRUE;
}
void fgPlatformCloseDisplay()
{
fghPlatformCloseDisplayEGL();
}
/**
* Close joystick and serial input devices
*/
void fgPlatformDeinitialiseInputDevices ( void )
{
fghCloseInputDevices ();
fgState.JoysticksInitialised = GL_FALSE;
fgState.InputDevsInitialised = GL_FALSE;
}

View File

@ -0,0 +1,52 @@
/*
* fg_input_devices_android.c
*
* Handles miscellaneous input devices via direct serial-port access.
*
* Written by Joe Krahn <krahn@niehs.nih.gov> 2005
* Copyright (c) 2005 Stephen J. Baker. All Rights Reserved.
* Copied for Platform code by Evan Felix <karcaw at gmail.com>
* Copyright 2012 (C) Sylvain Beucler
* Creation date: Thur Feb 2 2012
*
* 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
* PAWEL W. OLSZTA OR STEPHEN J. BAKER 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.
*/
#include <GL/freeglut.h>
#include "fg_internal.h"
typedef struct _serialport SERIALPORT;
#include <stdio.h>
/*
* This is only used if the user calls:
* glutDeviceGet(GLUT_HAS_DIAL_AND_BUTTON_BOX)
* and has old hardware called 'dials&buttons box'.
* http://www.reputable.com/sgipix/sgi-dialnbutton1.jpg
*
* Not implemented on Android :)
* http://sourceforge.net/mailarchive/message.php?msg_id=29209505
*/
void fgPlatformRegisterDialDevice ( const char *dial_device ) {
fgWarning("GLUT_HAS_DIAL_AND_BUTTON_BOX: not implemented");
}
SERIALPORT *fg_serial_open ( const char *device ) { return NULL; }
void fg_serial_close(SERIALPORT *port) {}
int fg_serial_getchar(SERIALPORT *port) { return EOF; }
int fg_serial_putchar(SERIALPORT *port, unsigned char ch) { return 0; }
void fg_serial_flush ( SERIALPORT *port ) {}

View File

@ -0,0 +1,120 @@
/*
* fg_internal_android.h
*
* The freeglut library private include file.
*
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#ifndef FREEGLUT_INTERNAL_ANDROID_H
#define FREEGLUT_INTERNAL_ANDROID_H
/* -- PLATFORM-SPECIFIC INCLUDES ------------------------------------------- */
/* Android OpenGL ES is accessed through EGL */
#include "egl/fg_internal_egl.h"
/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
/* The structure used by display initialization in fg_init.c */
typedef struct tagSFG_PlatformDisplay SFG_PlatformDisplay;
struct android_app;
struct tagSFG_PlatformDisplay
{
struct tagSFG_PlatformDisplayEGL egl;
EGLNativeWindowType single_native_window;
struct android_app* app;
};
typedef struct tagSFG_PlatformContext SFG_PlatformContext;
/* SFG_PlatformContext is used for SFG_Window.Window */
struct tagSFG_PlatformContext
{
struct tagSFG_PlatformContextEGL egl;
};
/**
* Virtual PAD (spots on touchscreen that simulate keys)
*/
struct vpad_state {
bool on;
bool left;
bool right;
bool up;
bool down;
};
struct touchscreen {
struct vpad_state vpad;
bool in_mmotion;
};
/* -- JOYSTICK-SPECIFIC STRUCTURES AND TYPES ------------------------------- */
/*
* Initial defines from "js.h" starting around line 33 with the existing "fg_joystick.c"
* interspersed
*/
/*
* We'll put these values in and that should
* allow the code to at least compile when there is
* no support. The JS open routine should error out
* and shut off all the code downstream anyway and if
* the application doesn't use a joystick we'll be fine.
*/
struct JS_DATA_TYPE
{
int buttons;
int x;
int y;
};
# define JS_RETURN (sizeof(struct JS_DATA_TYPE))
/* XXX It might be better to poll the operating system for the numbers of buttons and
* XXX axes and then dynamically allocate the arrays.
*/
# define _JS_MAX_AXES 16
typedef struct tagSFG_PlatformJoystick SFG_PlatformJoystick;
struct tagSFG_PlatformJoystick
{
struct JS_DATA_TYPE js;
char fname [ 128 ];
int fd;
};
/* Window's state description. This structure should be kept portable. */
typedef struct tagSFG_PlatformWindowState SFG_PlatformWindowState;
struct tagSFG_PlatformWindowState
{
char unused;
};
/* Menu font and color definitions */
#define FREEGLUT_MENU_FONT NULL
#define FREEGLUT_MENU_PEN_FORE_COLORS {0.0f, 0.0f, 0.0f, 1.0f}
#define FREEGLUT_MENU_PEN_BACK_COLORS {0.70f, 0.70f, 0.70f, 1.0f}
#define FREEGLUT_MENU_PEN_HFORE_COLORS {0.0f, 0.0f, 0.0f, 1.0f}
#define FREEGLUT_MENU_PEN_HBACK_COLORS {1.0f, 1.0f, 1.0f, 1.0f}
#endif /* FREEGLUT_INTERNAL_ANDROID_H */

View File

@ -0,0 +1,55 @@
/*
* fg_joystick_android.c
*
* Joystick handling code
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Steve Baker, <sjbaker1@airmail.net>
* Copied for Platform code by Evan Felix <karcaw at gmail.com>
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "fg_internal.h"
/**
* TODO: Android has no joysticks at the moment (only touchscreens/touchpads),
* but we could expose the accelerometer as a 3-axis joystick.
*/
void fgPlatformJoystickRawRead( SFG_Joystick* joy, int* buttons, float* axes )
{
fgWarning("fgPlatformJoystickRawRead: STUB\n");
}
void fgPlatformJoystickOpen( SFG_Joystick* joy )
{
fgWarning("fgPlatformJoystickOpen: STUB\n");
}
void fgPlatformJoystickInit( SFG_Joystick *fgJoystick[], int ident )
{
fgWarning("fgJoystick: STUB\n");
}
void fgPlatformJoystickClose ( int ident )
{
fgWarning("fgPlatformJoystickClose: STUB\n");
}

View File

@ -0,0 +1,558 @@
/*
* fg_main_android.c
*
* The Android-specific windows message processing methods.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Copied for Platform code by Evan Felix <karcaw at gmail.com>
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "fg_internal.h"
#include "egl/fg_window_egl.h"
#include <android/log.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "FreeGLUT", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "FreeGLUT", __VA_ARGS__))
#include <android/native_app_glue/android_native_app_glue.h>
#include <android/keycodes.h>
extern void fghOnReshapeNotify(SFG_Window *window, int width, int height, GLboolean forceNotify);
extern void fghOnPositionNotify(SFG_Window *window, int x, int y, GLboolean forceNotify);
extern void fgPlatformFullScreenToggle( SFG_Window *win );
extern void fgPlatformPositionWindow( SFG_Window *window, int x, int y );
extern void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height );
extern void fgPlatformPushWindow( SFG_Window *window );
extern void fgPlatformPopWindow( SFG_Window *window );
extern void fgPlatformHideWindow( SFG_Window *window );
extern void fgPlatformIconifyWindow( SFG_Window *window );
extern void fgPlatformShowWindow( SFG_Window *window );
static struct touchscreen touchscreen;
static unsigned char key_a2fg[256];
/* Cf. http://developer.android.com/reference/android/view/KeyEvent.html */
/* These codes are missing in <android/keycodes.h> */
/* Don't convert to enum, since it may conflict with future version of
that <android/keycodes.h> */
#define AKEYCODE_FORWARD_DEL 112
#define AKEYCODE_CTRL_LEFT 113
#define AKEYCODE_CTRL_RIGHT 114
#define AKEYCODE_MOVE_HOME 122
#define AKEYCODE_MOVE_END 123
#define AKEYCODE_INSERT 124
#define AKEYCODE_ESCAPE 127
#define AKEYCODE_F1 131
#define AKEYCODE_F2 132
#define AKEYCODE_F3 133
#define AKEYCODE_F4 134
#define AKEYCODE_F5 135
#define AKEYCODE_F6 136
#define AKEYCODE_F7 137
#define AKEYCODE_F8 138
#define AKEYCODE_F9 139
#define AKEYCODE_F10 140
#define AKEYCODE_F11 141
#define AKEYCODE_F12 142
#define EVENT_HANDLED 1
#define EVENT_NOT_HANDLED 0
/**
* Initialize Android keycode to GLUT keycode mapping
*/
static void key_init() {
memset(key_a2fg, 0, sizeof(key_a2fg));
key_a2fg[AKEYCODE_F1] = GLUT_KEY_F1;
key_a2fg[AKEYCODE_F2] = GLUT_KEY_F2;
key_a2fg[AKEYCODE_F3] = GLUT_KEY_F3;
key_a2fg[AKEYCODE_F4] = GLUT_KEY_F4;
key_a2fg[AKEYCODE_F5] = GLUT_KEY_F5;
key_a2fg[AKEYCODE_F6] = GLUT_KEY_F6;
key_a2fg[AKEYCODE_F7] = GLUT_KEY_F7;
key_a2fg[AKEYCODE_F8] = GLUT_KEY_F8;
key_a2fg[AKEYCODE_F9] = GLUT_KEY_F9;
key_a2fg[AKEYCODE_F10] = GLUT_KEY_F10;
key_a2fg[AKEYCODE_F11] = GLUT_KEY_F11;
key_a2fg[AKEYCODE_F12] = GLUT_KEY_F12;
key_a2fg[AKEYCODE_PAGE_UP] = GLUT_KEY_PAGE_UP;
key_a2fg[AKEYCODE_PAGE_DOWN] = GLUT_KEY_PAGE_DOWN;
key_a2fg[AKEYCODE_MOVE_HOME] = GLUT_KEY_HOME;
key_a2fg[AKEYCODE_MOVE_END] = GLUT_KEY_END;
key_a2fg[AKEYCODE_INSERT] = GLUT_KEY_INSERT;
key_a2fg[AKEYCODE_DPAD_UP] = GLUT_KEY_UP;
key_a2fg[AKEYCODE_DPAD_DOWN] = GLUT_KEY_DOWN;
key_a2fg[AKEYCODE_DPAD_LEFT] = GLUT_KEY_LEFT;
key_a2fg[AKEYCODE_DPAD_RIGHT] = GLUT_KEY_RIGHT;
key_a2fg[AKEYCODE_ALT_LEFT] = GLUT_KEY_ALT_L;
key_a2fg[AKEYCODE_ALT_RIGHT] = GLUT_KEY_ALT_R;
key_a2fg[AKEYCODE_SHIFT_LEFT] = GLUT_KEY_SHIFT_L;
key_a2fg[AKEYCODE_SHIFT_RIGHT] = GLUT_KEY_SHIFT_R;
key_a2fg[AKEYCODE_CTRL_LEFT] = GLUT_KEY_CTRL_L;
key_a2fg[AKEYCODE_CTRL_RIGHT] = GLUT_KEY_CTRL_R;
}
/**
* Convert an Android key event to ASCII.
*/
static unsigned char key_ascii(struct android_app* app, AInputEvent* event) {
int32_t code = AKeyEvent_getKeyCode(event);
/* Handle a few special cases: */
switch (code) {
case AKEYCODE_DEL:
return 8;
case AKEYCODE_FORWARD_DEL:
return 127;
case AKEYCODE_ESCAPE:
return 27;
}
/* Get usable JNI context */
JNIEnv* env = app->activity->env;
JavaVM* vm = app->activity->vm;
(*vm)->AttachCurrentThread(vm, &env, NULL);
jclass KeyEventClass = (*env)->FindClass(env, "android/view/KeyEvent");
jmethodID KeyEventConstructor = (*env)->GetMethodID(env, KeyEventClass, "<init>", "(II)V");
jobject keyEvent = (*env)->NewObject(env, KeyEventClass, KeyEventConstructor,
AKeyEvent_getAction(event), AKeyEvent_getKeyCode(event));
jmethodID KeyEvent_getUnicodeChar = (*env)->GetMethodID(env, KeyEventClass, "getUnicodeChar", "(I)I");
int ascii = (*env)->CallIntMethod(env, keyEvent, KeyEvent_getUnicodeChar, AKeyEvent_getMetaState(event));
/* LOGI("getUnicodeChar(%d) = %d ('%c')", AKeyEvent_getKeyCode(event), ascii, ascii); */
(*vm)->DetachCurrentThread(vm);
return ascii;
}
unsigned long fgPlatformSystemTime ( void )
{
struct timeval now;
gettimeofday( &now, NULL );
return now.tv_usec/1000 + now.tv_sec*1000;
}
/*
* Does the magic required to relinquish the CPU until something interesting
* happens.
*/
void fgPlatformSleepForEvents( fg_time_t msec )
{
/* Android's NativeActivity relies on a Looper/ALooper object to
notify about events. The Looper object is plugged on two
internal pipe(2)s to detect system and input events. Sadly you
can only ask the Looper for an event, not just ask whether
there is a pending event (and process it later). Consequently,
short of redesigning NativeActivity, we cannot
SleepForEvents. */
}
/**
* Process the next input event.
*/
int32_t handle_input(struct android_app* app, AInputEvent* event) {
SFG_Window* window = fgWindowByHandle(app->window);
if (window == NULL)
return EVENT_NOT_HANDLED;
/* FIXME: in Android, when a key is repeated, down
and up events happen most often at the exact same time. This
makes it impossible to animate based on key press time. */
/* e.g. down/up/wait/down/up rather than down/wait/down/wait/up */
/* This looks like a bug in the Android virtual keyboard system :/
Real buttons such as the Back button appear to work correctly
(series of down events with proper getRepeatCount value). */
if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) {
/* LOGI("action: %d", AKeyEvent_getAction(event)); */
/* LOGI("keycode: %d", code); */
int32_t code = AKeyEvent_getKeyCode(event);
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) {
int32_t keypress = 0;
unsigned char ascii = 0;
if ((keypress = key_a2fg[code]) && FETCH_WCB(*window, Special)) {
INVOKE_WCB(*window, Special, (keypress, window->State.MouseX, window->State.MouseY));
return EVENT_HANDLED;
} else if ((ascii = key_ascii(app, event)) && FETCH_WCB(*window, Keyboard)) {
INVOKE_WCB(*window, Keyboard, (ascii, window->State.MouseX, window->State.MouseY));
return EVENT_HANDLED;
}
}
else if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_UP) {
int32_t keypress = 0;
unsigned char ascii = 0;
if ((keypress = key_a2fg[code]) && FETCH_WCB(*window, Special)) {
INVOKE_WCB(*window, SpecialUp, (keypress, window->State.MouseX, window->State.MouseY));
return EVENT_HANDLED;
} else if ((ascii = key_ascii(app, event)) && FETCH_WCB(*window, Keyboard)) {
INVOKE_WCB(*window, KeyboardUp, (ascii, window->State.MouseX, window->State.MouseY));
return EVENT_HANDLED;
}
}
}
int32_t source = AInputEvent_getSource(event);
if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION
&& source == AINPUT_SOURCE_TOUCHSCREEN) {
int32_t action = AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK;
/* Pointer ID for clicks */
int32_t pidx = AMotionEvent_getAction(event) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
/* TODO: Handle multi-touch; also handle multiple sources/devices */
/* cf. http://sourceforge.net/mailarchive/forum.php?thread_name=20120518071314.GA28061%40perso.beuc.net&forum_name=freeglut-developer */
if (0) {
LOGI("motion action=%d index=%d source=%d", action, pidx, source);
int count = AMotionEvent_getPointerCount(event);
int i;
for (i = 0; i < count; i++) {
LOGI("multi(%d): %.01f,%.01f",
AMotionEvent_getPointerId(event, i),
AMotionEvent_getX(event, i), AMotionEvent_getY(event, i));
}
}
float x = AMotionEvent_getX(event, 0);
float y = AMotionEvent_getY(event, 0);
/* Virtual arrows PAD */
/* Don't interfere with existing mouse move event */
if (!touchscreen.in_mmotion) {
struct vpad_state prev_vpad = touchscreen.vpad;
touchscreen.vpad.left = touchscreen.vpad.right
= touchscreen.vpad.up = touchscreen.vpad.down = false;
/* int32_t width = ANativeWindow_getWidth(window->Window.Handle); */
int32_t height = ANativeWindow_getHeight(window->Window.Handle);
if (action == AMOTION_EVENT_ACTION_DOWN || action == AMOTION_EVENT_ACTION_MOVE) {
if ((x > 0 && x < 100) && (y > (height - 100) && y < height))
touchscreen.vpad.left = true;
if ((x > 200 && x < 300) && (y > (height - 100) && y < height))
touchscreen.vpad.right = true;
if ((x > 100 && x < 200) && (y > (height - 100) && y < height))
touchscreen.vpad.down = true;
if ((x > 100 && x < 200) && (y > (height - 200) && y < (height - 100)))
touchscreen.vpad.up = true;
}
if (action == AMOTION_EVENT_ACTION_DOWN &&
(touchscreen.vpad.left || touchscreen.vpad.right || touchscreen.vpad.down || touchscreen.vpad.up))
touchscreen.vpad.on = true;
if (action == AMOTION_EVENT_ACTION_UP)
touchscreen.vpad.on = false;
if (prev_vpad.left != touchscreen.vpad.left
|| prev_vpad.right != touchscreen.vpad.right
|| prev_vpad.up != touchscreen.vpad.up
|| prev_vpad.down != touchscreen.vpad.down
|| prev_vpad.on != touchscreen.vpad.on) {
if (FETCH_WCB(*window, Special)) {
if (prev_vpad.left == false && touchscreen.vpad.left == true)
INVOKE_WCB(*window, Special, (GLUT_KEY_LEFT, x, y));
else if (prev_vpad.right == false && touchscreen.vpad.right == true)
INVOKE_WCB(*window, Special, (GLUT_KEY_RIGHT, x, y));
else if (prev_vpad.up == false && touchscreen.vpad.up == true)
INVOKE_WCB(*window, Special, (GLUT_KEY_UP, x, y));
else if (prev_vpad.down == false && touchscreen.vpad.down == true)
INVOKE_WCB(*window, Special, (GLUT_KEY_DOWN, x, y));
}
if (FETCH_WCB(*window, SpecialUp)) {
if (prev_vpad.left == true && touchscreen.vpad.left == false)
INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_LEFT, x, y));
if (prev_vpad.right == true && touchscreen.vpad.right == false)
INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_RIGHT, x, y));
if (prev_vpad.up == true && touchscreen.vpad.up == false)
INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_UP, x, y));
if (prev_vpad.down == true && touchscreen.vpad.down == false)
INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_DOWN, x, y));
}
return EVENT_HANDLED;
}
}
/* Normal mouse events */
if (!touchscreen.vpad.on) {
window->State.MouseX = x;
window->State.MouseY = y;
if (action == AMOTION_EVENT_ACTION_DOWN && FETCH_WCB(*window, Mouse)) {
touchscreen.in_mmotion = true;
INVOKE_WCB(*window, Mouse, (GLUT_LEFT_BUTTON, GLUT_DOWN, x, y));
} else if (action == AMOTION_EVENT_ACTION_UP && FETCH_WCB(*window, Mouse)) {
touchscreen.in_mmotion = false;
INVOKE_WCB(*window, Mouse, (GLUT_LEFT_BUTTON, GLUT_UP, x, y));
} else if (action == AMOTION_EVENT_ACTION_MOVE && FETCH_WCB(*window, Motion)) {
INVOKE_WCB(*window, Motion, (x, y));
}
}
return EVENT_HANDLED;
}
/* Let Android handle other events (e.g. Back and Menu buttons) */
return EVENT_NOT_HANDLED;
}
/**
* Process the next main command.
*/
void handle_cmd(struct android_app* app, int32_t cmd) {
SFG_Window* window = fgWindowByHandle(app->window); /* may be NULL */
switch (cmd) {
/* App life cycle, in that order: */
case APP_CMD_START:
LOGI("handle_cmd: APP_CMD_START");
break;
case APP_CMD_RESUME:
LOGI("handle_cmd: APP_CMD_RESUME");
/* Cf. fgPlatformProcessSingleEvent */
break;
case APP_CMD_INIT_WINDOW: /* surfaceCreated */
/* The window is being shown, get it ready. */
LOGI("handle_cmd: APP_CMD_INIT_WINDOW %p", app->window);
fgDisplay.pDisplay.single_native_window = app->window;
/* start|resume: glPlatformOpenWindow was waiting for Handle to be
defined and will now continue processing */
break;
case APP_CMD_GAINED_FOCUS:
LOGI("handle_cmd: APP_CMD_GAINED_FOCUS");
break;
case APP_CMD_WINDOW_RESIZED:
LOGI("handle_cmd: APP_CMD_WINDOW_RESIZED");
if (window->Window.pContext.egl.Surface != EGL_NO_SURFACE)
/* Make ProcessSingleEvent detect the new size, only available
after the next SwapBuffer */
glutPostRedisplay();
break;
case APP_CMD_SAVE_STATE: /* onSaveInstanceState */
/* The system has asked us to save our current state, when it
pauses the application without destroying it right after. */
app->savedState = strdup("Detect me as non-NULL on next android_main");
app->savedStateSize = strlen(app->savedState) + 1;
LOGI("handle_cmd: APP_CMD_SAVE_STATE");
break;
case APP_CMD_PAUSE:
LOGI("handle_cmd: APP_CMD_PAUSE");
/* Cf. fgPlatformProcessSingleEvent */
break;
case APP_CMD_LOST_FOCUS:
LOGI("handle_cmd: APP_CMD_LOST_FOCUS");
break;
case APP_CMD_TERM_WINDOW: /* surfaceDestroyed */
/* The application is being hidden, but may be restored */
LOGI("handle_cmd: APP_CMD_TERM_WINDOW");
fghPlatformCloseWindowEGL(window);
fgDisplay.pDisplay.single_native_window = NULL;
break;
case APP_CMD_STOP:
LOGI("handle_cmd: APP_CMD_STOP");
break;
case APP_CMD_DESTROY: /* Activity.onDestroy */
LOGI("handle_cmd: APP_CMD_DESTROY");
/* User closed the application for good, let's kill the window */
{
/* Can't use fgWindowByHandle as app->window is NULL */
SFG_Window* window = fgStructure.CurrentWindow;
if (window != NULL) {
fgDestroyWindow(window);
} else {
LOGI("APP_CMD_DESTROY: No current window");
}
}
/* glue has already set android_app->destroyRequested=1 */
break;
case APP_CMD_CONFIG_CHANGED:
/* Handle rotation / orientation change */
LOGI("handle_cmd: APP_CMD_CONFIG_CHANGED");
break;
case APP_CMD_LOW_MEMORY:
LOGI("handle_cmd: APP_CMD_LOW_MEMORY");
break;
default:
LOGI("handle_cmd: unhandled cmd=%d", cmd);
}
}
void fgPlatformOpenWindow( SFG_Window* window, const char* title,
GLboolean positionUse, int x, int y,
GLboolean sizeUse, int w, int h,
GLboolean gameMode, GLboolean isSubWindow );
void fgPlatformProcessSingleEvent ( void )
{
/* When the screen is resized, the window handle still points to the
old window until the next SwapBuffer, while it's crucial to set
the size (onShape) correctly before the next onDisplay callback.
Plus we don't know if the next SwapBuffer already occurred at the
time we process the event (e.g. during onDisplay). */
/* So we do the check each time rather than on event. */
/* Interestingly, on a Samsung Galaxy S/PowerVR SGX540 GPU/Android
2.3, that next SwapBuffer is fake (but still necessary to get the
new size). */
SFG_Window* window = fgStructure.CurrentWindow;
if (window != NULL && window->Window.Handle != NULL) {
int32_t width = ANativeWindow_getWidth(window->Window.Handle);
int32_t height = ANativeWindow_getHeight(window->Window.Handle);
fghOnReshapeNotify(window,width,height,GL_FALSE);
}
/* Read pending event. */
int ident;
int events;
struct android_poll_source* source;
/* This is called "ProcessSingleEvent" but this means we'd only
process ~60 (screen Hz) mouse events per second, plus other ports
are processing all events already. So let's process all pending
events. */
/* if ((ident=ALooper_pollOnce(0, NULL, &events, (void**)&source)) >= 0) { */
while ((ident=ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0) {
/* Process this event. */
if (source != NULL) {
source->process(source->app, source);
}
}
/* If we're not in RESUME state, Android paused us, so wait */
struct android_app* app = fgDisplay.pDisplay.app;
if (app->destroyRequested != 1 && app->activityState != APP_CMD_RESUME) {
INVOKE_WCB(*window, AppStatus, (GLUT_APPSTATUS_PAUSE));
int FOREVER = -1;
while (app->destroyRequested != 1 && (app->activityState != APP_CMD_RESUME)) {
if ((ident=ALooper_pollOnce(FOREVER, NULL, &events, (void**)&source)) >= 0) {
/* Process this event. */
if (source != NULL) {
source->process(source->app, source);
}
}
}
/* Coming back from a pause: */
/* - Recreate window context and surface */
/* - Call user-defined hook to restore resources (textures...) */
/* - Exit pause loop */
if (app->destroyRequested != 1) {
/* Android is full-screen only, simplified call.. */
/* Ideally we'd have a fgPlatformReopenWindow() */
/* If we're hidden by a non-fullscreen or translucent activity,
we'll be paused but not stopped, and keep the current
surface; in which case fgPlatformOpenWindow will no-op. */
fgPlatformOpenWindow(window, "", GL_FALSE, 0, 0, GL_FALSE, 0, 0, GL_FALSE, GL_FALSE);
/* TODO: should there be a whole GLUT_INIT_WORK forced? probably...
* Could queue that up in APP_CMD_TERM_WINDOW handler, but it'll
* be not possible to ensure InitContext CB gets called before
* Resume CB like that.. so maybe just force calling initContext CB
* here is best. Or we could force work on the window in question..
* 1) save old work mask, 2) set mask to init only, 3) call fgProcessWork directly
* 4) set work mask back to the one saved in step 1.
*/
if (!FETCH_WCB(*window, InitContext))
fgWarning("Resuming application, but no callback to reload context resources (glutInitContextFunc)");
}
INVOKE_WCB(*window, AppStatus, (GLUT_APPSTATUS_RESUME));
}
}
void fgPlatformMainLoopPreliminaryWork ( void )
{
LOGI("fgPlatformMainLoopPreliminaryWork\n");
key_init();
/* Make sure glue isn't stripped. */
/* JNI entry points need to be bundled even when linking statically */
app_dummy();
}
/* deal with work list items */
void fgPlatformInitWork(SFG_Window* window)
{
/* notify windowStatus/visibility */
INVOKE_WCB( *window, WindowStatus, ( GLUT_FULLY_RETAINED ) );
/* Position callback, always at 0,0 */
fghOnPositionNotify(window, 0, 0, GL_TRUE);
/* Size gets notified on window creation with size detection in mainloop above
* XXX CHECK: does this messages happen too early like on windows,
* so client code cannot have registered a callback yet and the message
* is thus never received by client?
*/
}
void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask)
{
if (workMask & GLUT_FULL_SCREEN_WORK)
fgPlatformFullScreenToggle( window );
if (workMask & GLUT_POSITION_WORK)
fgPlatformPositionWindow( window, window->State.DesiredXpos, window->State.DesiredYpos );
if (workMask & GLUT_SIZE_WORK)
fgPlatformReshapeWindow ( window, window->State.DesiredWidth, window->State.DesiredHeight );
if (workMask & GLUT_ZORDER_WORK)
{
if (window->State.DesiredZOrder < 0)
fgPlatformPushWindow( window );
else
fgPlatformPopWindow( window );
}
}
void fgPlatformVisibilityWork(SFG_Window* window)
{
/* Visibility status of window should get updated in the window message handlers
* For now, none of these functions called below do anything, so don't worry
* about it
*/
SFG_Window *win = window;
switch (window->State.DesiredVisibility)
{
case DesireHiddenState:
fgPlatformHideWindow( window );
break;
case DesireIconicState:
/* Call on top-level window */
while (win->Parent)
win = win->Parent;
fgPlatformIconifyWindow( win );
break;
case DesireNormalState:
fgPlatformShowWindow( window );
break;
}
}
/* dummy functions, not applicable on android */
void fgPlatformSetColor(int idx, float r, float g, float b)
{
}
float fgPlatformGetColor(int idx, int comp)
{
}
void fgPlatformCopyColormap(int win)
{
}

View File

@ -0,0 +1,37 @@
/*
* fg_main_android.h
*
* The Android-specific windows message processing methods.
*
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#ifndef __FG_MAIN_ANDROID_H__
#define __FG_MAIN_ANDROID_H__
#include <GL/freeglut.h>
#include "fg_internal.h"
extern void fgPlatformProcessSingleEvent(void);
extern unsigned long fgPlatformSystemTime(void);
extern void fgPlatformSleepForEvents(fg_time_t msec);
extern void fgPlatformMainLoopPreliminaryWork(void);
#endif

View File

@ -0,0 +1,169 @@
/*
* fg_runtime_android.c
*
* Android runtime
*
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
/* Parts taken from Android NDK's 'native-activity' sample: */
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <jni.h>
#include <android/log.h>
#include <android/asset_manager.h>
#include <android/native_window.h>
#include "android/native_app_glue/android_native_app_glue.h"
#include "android/fg_main_android.h"
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "FreeGLUT-jnicb", __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "FreeGLUT-jnicb", __VA_ARGS__))
/* Cf. fg_main_android.c */
extern int32_t handle_input(struct android_app* app, AInputEvent* event);
extern void handle_cmd(struct android_app* app, int32_t cmd);
extern int main(int argc, char* argv[]);
/** NativeActivity Callbacks **/
/* Caution: they are called in the native_activity thread, not the
FreeGLUT thread. Use android_app_write_cmd. */
/* Could be used instead of onNativeWindowRedrawNeeded */
/* Deals with status bar presence */
static void onContentRectChanged(ANativeActivity* activity, const ARect* rect) {
LOGI("onContentRectChanged: l=%d,t=%d,r=%d,b=%d", rect->left, rect->top, rect->right, rect->bottom);
}
/* Bug: not called during a resize in android-9, only once on startup :/ */
static void onNativeWindowResized(ANativeActivity* activity, ANativeWindow* window) {
LOGI("onNativeWindowResized: %p\n", (void*)activity);
}
/* Called after a resize, compensate broken onNativeWindowResized */
static void onNativeWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* window) {
LOGI("onNativeWindowRedrawNeeded: %p\n", (void*)activity);
struct android_app* app = (struct android_app*)activity->instance;
android_app_write_cmd(app, APP_CMD_WINDOW_RESIZED);
}
/**
* Extract all .apk assets to the application directory so they can be
* accessed using accessed.
* TODO: parse directories recursively
*/
static void extract_assets(struct android_app* app) {
/* Get usable JNI context */
JNIEnv* env = app->activity->env;
JavaVM* vm = app->activity->vm;
(*vm)->AttachCurrentThread(vm, &env, NULL);
{
/* Get a handle on our calling NativeActivity class */
jclass activityClass = (*env)->GetObjectClass(env, app->activity->clazz);
/* Get path to cache dir (/data/data/org.myapp/cache) */
jmethodID getCacheDir = (*env)->GetMethodID(env, activityClass, "getCacheDir", "()Ljava/io/File;");
jobject file = (*env)->CallObjectMethod(env, app->activity->clazz, getCacheDir);
jclass fileClass = (*env)->FindClass(env, "java/io/File");
jmethodID getAbsolutePath = (*env)->GetMethodID(env, fileClass, "getAbsolutePath", "()Ljava/lang/String;");
jstring jpath = (jstring)(*env)->CallObjectMethod(env, file, getAbsolutePath);
const char* app_dir = (*env)->GetStringUTFChars(env, jpath, NULL);
/* chdir in the application cache directory */
LOGI("app_dir: %s", app_dir);
chdir(app_dir);
(*env)->ReleaseStringUTFChars(env, jpath, app_dir);
/* Pre-extract assets, to avoid Android-specific file opening */
{
AAssetManager* mgr = app->activity->assetManager;
AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
const char* filename = (const char*)NULL;
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);
char buf[BUFSIZ];
int nb_read = 0;
FILE* out = fopen(filename, "w");
while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)
fwrite(buf, nb_read, 1, out);
fclose(out);
AAsset_close(asset);
}
AAssetDir_close(assetDir);
}
}
(*vm)->DetachCurrentThread(vm);
}
/**
* This is the main entry point of a native application that is using
* android_native_app_glue. It runs in its own thread, with its own
* event loop for receiving input events and doing other things.
*/
void android_main(struct android_app* app) {
LOGI("android_main savedState=%p", app->savedState);
/* Register window resize callback */
app->activity->callbacks->onNativeWindowResized = onNativeWindowResized;
app->activity->callbacks->onContentRectChanged = onContentRectChanged;
app->activity->callbacks->onNativeWindowRedrawNeeded = onNativeWindowRedrawNeeded;
app->onAppCmd = handle_cmd;
app->onInputEvent = handle_input;
extract_assets(app);
/* Call user's main */
{
char progname[5] = "self";
char* argv[] = {progname, NULL};
fgDisplay.pDisplay.app = app;
main(1, argv);
/* FreeGLUT will exit() by itself if
GLUT_ACTION_ON_WINDOW_CLOSE == GLUT_ACTION_EXIT */
}
LOGI("android_main: end");
/* Let NativeActivity restart us */
/* Users may want to forcibly exit() in their main() anyway because
NativeActivity doesn't dlclose() us, so all statically-assigned
variables keep their old values on restart.. */
}

View File

@ -0,0 +1,58 @@
/*
* fg_spaceball_android.c
*
* Spaceball support for Windows
*
* Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
* Written by Evan Felix <karcaw at gmail.com>
* Creation date: Sat Feb 4, 2012
*
* 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
* PAWEL W. OLSZTA 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.
*/
/*
* This code is a very complicated way of doing nothing.
* But is needed for Android platform builds.
*/
#include <GL/freeglut.h>
#include "fg_internal.h"
void fgPlatformInitializeSpaceball(void)
{
return;
}
void fgPlatformSpaceballClose(void)
{
return;
}
int fgPlatformHasSpaceball(void)
{
return 0;
}
int fgPlatformSpaceballNumButtons(void)
{
return 0;
}
void fgPlatformSpaceballSetWindow(SFG_Window *window)
{
return;
}

View File

@ -0,0 +1,96 @@
/*
* fg_state_android.c
*
* Android-specific freeglut state query methods.
*
* Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
* Written by John F. Fay, <fayjf@sourceforge.net>
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include <stdio.h>
#include <android/native_window.h>
#include "fg_internal.h"
#include "egl/fg_state_egl.h"
int fgPlatformGlutDeviceGet ( GLenum eWhat )
{
switch( eWhat )
{
case GLUT_HAS_KEYBOARD:
/* Android has a keyboard, though it may be virtual. */
return 1;
case GLUT_HAS_MOUSE:
/* Android has a touchscreen; until we get proper touchscreen
support, consider it as a mouse. */
return 1 ;
case GLUT_NUM_MOUSE_BUTTONS:
/* Android has a touchscreen; until we get proper touchscreen
support, consider it as a 1-button mouse. */
return 1;
default:
fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
break;
}
/* And now -- the failure. */
return -1;
}
int fgPlatformGlutGet ( GLenum eWhat )
{
switch (eWhat) {
/* One full-screen window only */
case GLUT_WINDOW_X:
case GLUT_WINDOW_Y:
case GLUT_WINDOW_BORDER_WIDTH:
case GLUT_WINDOW_HEADER_HEIGHT:
return 0;
case GLUT_WINDOW_WIDTH:
case GLUT_WINDOW_HEIGHT:
{
if ( fgStructure.CurrentWindow == NULL )
return 0;
int32_t width = ANativeWindow_getWidth(fgStructure.CurrentWindow->Window.Handle);
int32_t height = ANativeWindow_getHeight(fgStructure.CurrentWindow->Window.Handle);
switch ( eWhat )
{
case GLUT_WINDOW_WIDTH:
return width;
case GLUT_WINDOW_HEIGHT:
return height;
}
}
case GLUT_WINDOW_COLORMAP_SIZE:
/* 0 for RGBA/non-indexed mode */
/* Under Android and GLES more generally, no indexed-mode */
return 0;
default:
return fghPlatformGlutGetEGL(eWhat);
}
return -1;
}

View File

@ -0,0 +1,36 @@
/*
* fg_structure_android.c
*
* Windows and menus need tree structure
*
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "fg_internal.h"
#include "egl/fg_structure_egl.h"
/**
* Initialize default platform-specific fields in SFG_Window
*/
void fgPlatformCreateWindow ( SFG_Window *window )
{
fghPlatformCreateWindowEGL(window);
}

View File

@ -0,0 +1,183 @@
/*
* fg_window_android.c
*
* Window management methods for Android
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Copied for Platform code by Evan Felix <karcaw at gmail.com>
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#define FREEGLUT_BUILDING_LIB
#include <GL/freeglut.h>
#include "fg_internal.h"
#include "egl/fg_window_egl.h"
#include <android/native_app_glue/android_native_app_glue.h>
/*
* Opens a window. Requires a SFG_Window object created and attached
* to the freeglut structure. OpenGL context is created here.
*/
void fgPlatformOpenWindow( SFG_Window* window, const char* title,
GLboolean positionUse, int x, int y,
GLboolean sizeUse, int w, int h,
GLboolean gameMode, GLboolean isSubWindow )
{
/* TODO: only one full-screen window possible? */
if (fgDisplay.pDisplay.single_native_window != NULL) {
fgWarning("You can't have more than one window on Android");
return;
}
/* First, wait until Activity surface is available */
/* Normally events are processed through glutMainLoop(), but the
user didn't call it yet, and the Android may not have initialized
the View yet. So we need to wait for that to happen. */
/* We can't return from this function before the OpenGL context is
properly made current with a valid surface. So we wait for the
surface. */
while (fgDisplay.pDisplay.single_native_window == NULL) {
/* APP_CMD_INIT_WINDOW will do the job */
int ident;
int events;
struct android_poll_source* source;
if ((ident=ALooper_pollOnce(0, NULL, &events, (void**)&source)) >= 0)
if (source != NULL) source->process(source->app, source);
/* fgPlatformProcessSingleEvent(); */
}
window->Window.Handle = fgDisplay.pDisplay.single_native_window;
window->State.WorkMask |= GLUT_INIT_WORK;
/* Create context */
fghChooseConfig(&window->Window.pContext.egl.Config);
window->Window.Context = fghCreateNewContextEGL(window);
EGLDisplay display = fgDisplay.pDisplay.egl.Display;
/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
* guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
* As soon as we picked a EGLConfig, we can safely reconfigure the
* ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
EGLint vid;
eglGetConfigAttrib(display, window->Window.pContext.egl.Config,
EGL_NATIVE_VISUAL_ID, &vid);
ANativeWindow_setBuffersGeometry(window->Window.Handle, 0, 0, vid);
fghPlatformOpenWindowEGL(window);
/* Bind context to the current thread if it's lost */
if (eglGetCurrentContext() == EGL_NO_CONTEXT &&
eglMakeCurrent(fgDisplay.pDisplay.egl.Display,
window->Window.pContext.egl.Surface,
window->Window.pContext.egl.Surface,
window->Window.Context) == EGL_FALSE)
fgError("eglMakeCurrent: err=%x\n", eglGetError());
window->State.Visible = GL_TRUE;
}
/*
* Request a window resize
*/
void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height )
{
fprintf(stderr, "fgPlatformReshapeWindow: STUB\n");
}
/*
* Closes a window, destroying the frame and OpenGL context
*/
void fgPlatformCloseWindow( SFG_Window* window )
{
fghPlatformCloseWindowEGL(window);
/* Window pre-created by Android, no way to delete it */
}
/*
* This function makes the specified window visible
*/
void fgPlatformShowWindow( SFG_Window *window )
{
fprintf(stderr, "fgPlatformShowWindow: STUB\n");
}
/*
* This function hides the specified window
*/
void fgPlatformHideWindow( SFG_Window *window )
{
fprintf(stderr, "fgPlatformHideWindow: STUB\n");
}
/*
* Iconify the specified window (top-level windows only)
*/
void fgPlatformIconifyWindow( SFG_Window *window )
{
fprintf(stderr, "fgPlatformGlutIconifyWindow: STUB\n");
}
/*
* Set the current window's title
*/
void fgPlatformGlutSetWindowTitle( const char* title )
{
fprintf(stderr, "fgPlatformGlutSetWindowTitle: STUB\n");
}
/*
* Set the current window's iconified title
*/
void fgPlatformGlutSetIconTitle( const char* title )
{
fprintf(stderr, "fgPlatformGlutSetIconTitle: STUB\n");}
/*
* Change the specified window's position
*/
void fgPlatformPositionWindow( SFG_Window *window, int x, int y )
{
fprintf(stderr, "fgPlatformPositionWindow: STUB\n");
}
/*
* Lowers the specified window (by Z order change)
*/
void fgPlatformPushWindow( SFG_Window *window )
{
fprintf(stderr, "fgPlatformPushWindow: STUB\n");
}
/*
* Raises the specified window (by Z order change)
*/
void fgPlatformPopWindow( SFG_Window *window )
{
fprintf(stderr, "fgPlatformPopWindow: STUB\n");
}
/*
* Toggle the window's full screen state.
*/
void fgPlatformFullScreenToggle( SFG_Window *win )
{
fprintf(stderr, "fgPlatformFullScreenToggle: STUB\n");
}

View File

@ -0,0 +1,7 @@
This code is copied from the Android NDK r7, from
source/android/native_app_glue/ .
A few GCC warnings were suppressed.
'android_app_write_cmd' was made non-static so that resize events can
be injected from FreeGLUT.

View File

@ -0,0 +1,436 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <jni.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/resource.h>
#include "android_native_app_glue.h"
#include <android/log.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__))
static void free_saved_state(struct android_app* android_app) {
pthread_mutex_lock(&android_app->mutex);
if (android_app->savedState != NULL) {
free(android_app->savedState);
android_app->savedState = NULL;
android_app->savedStateSize = 0;
}
pthread_mutex_unlock(&android_app->mutex);
}
int8_t android_app_read_cmd(struct android_app* android_app) {
int8_t cmd;
if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) {
switch (cmd) {
case APP_CMD_SAVE_STATE:
free_saved_state(android_app);
break;
}
return cmd;
} else {
LOGI("No data on command pipe!");
}
return -1;
}
static void print_cur_config(struct android_app* android_app) {
char lang[2], country[2];
AConfiguration_getLanguage(android_app->config, lang);
AConfiguration_getCountry(android_app->config, country);
LOGI("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d "
"keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d "
"modetype=%d modenight=%d",
AConfiguration_getMcc(android_app->config),
AConfiguration_getMnc(android_app->config),
lang[0], lang[1], country[0], country[1],
AConfiguration_getOrientation(android_app->config),
AConfiguration_getTouchscreen(android_app->config),
AConfiguration_getDensity(android_app->config),
AConfiguration_getKeyboard(android_app->config),
AConfiguration_getNavigation(android_app->config),
AConfiguration_getKeysHidden(android_app->config),
AConfiguration_getNavHidden(android_app->config),
AConfiguration_getSdkVersion(android_app->config),
AConfiguration_getScreenSize(android_app->config),
AConfiguration_getScreenLong(android_app->config),
AConfiguration_getUiModeType(android_app->config),
AConfiguration_getUiModeNight(android_app->config));
}
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
switch (cmd) {
case APP_CMD_INPUT_CHANGED:
LOGI("APP_CMD_INPUT_CHANGED\n");
pthread_mutex_lock(&android_app->mutex);
if (android_app->inputQueue != NULL) {
AInputQueue_detachLooper(android_app->inputQueue);
}
android_app->inputQueue = android_app->pendingInputQueue;
if (android_app->inputQueue != NULL) {
LOGI("Attaching input queue to looper");
AInputQueue_attachLooper(android_app->inputQueue,
android_app->looper, LOOPER_ID_INPUT, NULL,
&android_app->inputPollSource);
}
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_INIT_WINDOW:
LOGI("APP_CMD_INIT_WINDOW\n");
pthread_mutex_lock(&android_app->mutex);
android_app->window = android_app->pendingWindow;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_TERM_WINDOW:
LOGI("APP_CMD_TERM_WINDOW\n");
pthread_cond_broadcast(&android_app->cond);
break;
case APP_CMD_RESUME:
case APP_CMD_START:
case APP_CMD_PAUSE:
case APP_CMD_STOP:
LOGI("activityState=%d\n", cmd);
pthread_mutex_lock(&android_app->mutex);
android_app->activityState = cmd;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_CONFIG_CHANGED:
LOGI("APP_CMD_CONFIG_CHANGED\n");
AConfiguration_fromAssetManager(android_app->config,
android_app->activity->assetManager);
print_cur_config(android_app);
break;
case APP_CMD_DESTROY:
LOGI("APP_CMD_DESTROY\n");
android_app->destroyRequested = 1;
break;
}
}
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
switch (cmd) {
case APP_CMD_TERM_WINDOW:
LOGI("APP_CMD_TERM_WINDOW\n");
pthread_mutex_lock(&android_app->mutex);
android_app->window = NULL;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_SAVE_STATE:
LOGI("APP_CMD_SAVE_STATE\n");
pthread_mutex_lock(&android_app->mutex);
android_app->stateSaved = 1;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_RESUME:
free_saved_state(android_app);
break;
}
}
void app_dummy() {
}
static void android_app_destroy(struct android_app* android_app) {
LOGI("android_app_destroy!");
free_saved_state(android_app);
pthread_mutex_lock(&android_app->mutex);
if (android_app->inputQueue != NULL) {
AInputQueue_detachLooper(android_app->inputQueue);
}
AConfiguration_delete(android_app->config);
android_app->destroyed = 1;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
/* // Can't touch android_app object after this. */
}
static void process_input(struct android_app* app, struct android_poll_source* source) {
AInputEvent* event = NULL;
if (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
LOGI("New input event: type=%d\n", AInputEvent_getType(event));
if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
return;
}
{
int32_t handled = 0;
if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
AInputQueue_finishEvent(app->inputQueue, event, handled);
}
} else {
LOGI("Failure reading next input event: %s\n", strerror(errno));
}
}
static void process_cmd(struct android_app* app, struct android_poll_source* source) {
int8_t cmd = android_app_read_cmd(app);
android_app_pre_exec_cmd(app, cmd);
if (app->onAppCmd != NULL) app->onAppCmd(app, cmd);
android_app_post_exec_cmd(app, cmd);
}
static void* android_app_entry(void* param) {
struct android_app* android_app = (struct android_app*)param;
ALooper* looper;
android_app->config = AConfiguration_new();
AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager);
print_cur_config(android_app);
android_app->cmdPollSource.id = LOOPER_ID_MAIN;
android_app->cmdPollSource.app = android_app;
android_app->cmdPollSource.process = process_cmd;
android_app->inputPollSource.id = LOOPER_ID_INPUT;
android_app->inputPollSource.app = android_app;
android_app->inputPollSource.process = process_input;
looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL,
&android_app->cmdPollSource);
android_app->looper = looper;
pthread_mutex_lock(&android_app->mutex);
android_app->running = 1;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
android_main(android_app);
android_app_destroy(android_app);
return NULL;
}
/* // -------------------------------------------------------------------- */
/* // Native activity interaction (called from main thread) */
/* // -------------------------------------------------------------------- */
static struct android_app* android_app_create(ANativeActivity* activity,
void* savedState, size_t savedStateSize) {
struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app));
int msgpipe[2];
pthread_attr_t attr;
memset(android_app, 0, sizeof(struct android_app));
android_app->activity = activity;
pthread_mutex_init(&android_app->mutex, NULL);
pthread_cond_init(&android_app->cond, NULL);
if (savedState != NULL) {
android_app->savedState = malloc(savedStateSize);
android_app->savedStateSize = savedStateSize;
memcpy(android_app->savedState, savedState, savedStateSize);
}
if (pipe(msgpipe)) {
LOGI("could not create pipe: %s", strerror(errno));
}
android_app->msgread = msgpipe[0];
android_app->msgwrite = msgpipe[1];
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&android_app->thread, &attr, android_app_entry, android_app);
/* // Wait for thread to start. */
pthread_mutex_lock(&android_app->mutex);
while (!android_app->running) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
return android_app;
}
/* static */void android_app_write_cmd(struct android_app* android_app, int8_t cmd) {
if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) {
LOGI("Failure writing android_app cmd: %s\n", strerror(errno));
}
}
static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) {
pthread_mutex_lock(&android_app->mutex);
android_app->pendingInputQueue = inputQueue;
android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED);
while (android_app->inputQueue != android_app->pendingInputQueue) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
}
static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) {
pthread_mutex_lock(&android_app->mutex);
if (android_app->pendingWindow != NULL) {
android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW);
}
android_app->pendingWindow = window;
if (window != NULL) {
android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW);
}
while (android_app->window != android_app->pendingWindow) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
}
static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) {
pthread_mutex_lock(&android_app->mutex);
android_app_write_cmd(android_app, cmd);
while (android_app->activityState != cmd) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
}
static void android_app_free(struct android_app* android_app) {
pthread_mutex_lock(&android_app->mutex);
android_app_write_cmd(android_app, APP_CMD_DESTROY);
while (!android_app->destroyed) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
close(android_app->msgread);
close(android_app->msgwrite);
pthread_cond_destroy(&android_app->cond);
pthread_mutex_destroy(&android_app->mutex);
free(android_app);
}
static void onDestroy(ANativeActivity* activity) {
LOGI("Destroy: %p\n", (void*)activity);
android_app_free((struct android_app*)activity->instance);
}
static void onStart(ANativeActivity* activity) {
LOGI("Start: %p\n", (void*)activity);
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START);
}
static void onResume(ANativeActivity* activity) {
LOGI("Resume: %p\n", (void*)activity);
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME);
}
static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) {
struct android_app* android_app = (struct android_app*)activity->instance;
void* savedState = NULL;
LOGI("SaveInstanceState: %p\n", (void*)activity);
pthread_mutex_lock(&android_app->mutex);
android_app->stateSaved = 0;
android_app_write_cmd(android_app, APP_CMD_SAVE_STATE);
while (!android_app->stateSaved) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
if (android_app->savedState != NULL) {
savedState = android_app->savedState;
*outLen = android_app->savedStateSize;
android_app->savedState = NULL;
android_app->savedStateSize = 0;
}
pthread_mutex_unlock(&android_app->mutex);
return savedState;
}
static void onPause(ANativeActivity* activity) {
LOGI("Pause: %p\n", (void*)activity);
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE);
}
static void onStop(ANativeActivity* activity) {
LOGI("Stop: %p\n", (void*)activity);
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP);
}
static void onConfigurationChanged(ANativeActivity* activity) {
struct android_app* android_app = (struct android_app*)activity->instance;
LOGI("ConfigurationChanged: %p\n", (void*)activity);
android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED);
}
static void onLowMemory(ANativeActivity* activity) {
struct android_app* android_app = (struct android_app*)activity->instance;
LOGI("LowMemory: %p\n", (void*)activity);
android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY);
}
static void onWindowFocusChanged(ANativeActivity* activity, int focused) {
LOGI("WindowFocusChanged: %p -- %d\n", (void*)activity, focused);
android_app_write_cmd((struct android_app*)activity->instance,
focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS);
}
static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) {
LOGI("NativeWindowCreated: %p -- %p\n", (void*)activity, (void*)window);
android_app_set_window((struct android_app*)activity->instance, window);
}
static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) {
LOGI("NativeWindowDestroyed: %p -- %p\n", (void*)activity, (void*)window);
android_app_set_window((struct android_app*)activity->instance, NULL);
}
static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) {
LOGI("InputQueueCreated: %p -- %p\n", (void*)activity, (void*)queue);
android_app_set_input((struct android_app*)activity->instance, queue);
}
static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) {
LOGI("InputQueueDestroyed: %p -- %p\n", (void*)activity, (void*)queue);
android_app_set_input((struct android_app*)activity->instance, NULL);
}
void ANativeActivity_onCreate(ANativeActivity* activity,
void* savedState, size_t savedStateSize) {
LOGI("Creating: %p\n", (void*)activity);
activity->callbacks->onDestroy = onDestroy;
activity->callbacks->onStart = onStart;
activity->callbacks->onResume = onResume;
activity->callbacks->onSaveInstanceState = onSaveInstanceState;
activity->callbacks->onPause = onPause;
activity->callbacks->onStop = onStop;
activity->callbacks->onConfigurationChanged = onConfigurationChanged;
activity->callbacks->onLowMemory = onLowMemory;
activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
activity->callbacks->onInputQueueCreated = onInputQueueCreated;
activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
activity->instance = android_app_create(activity, savedState, savedStateSize);
}

View File

@ -0,0 +1,351 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef _ANDROID_NATIVE_APP_GLUE_H
#define _ANDROID_NATIVE_APP_GLUE_H
#include <poll.h>
#include <pthread.h>
#include <sched.h>
#include <android/configuration.h>
#include <android/looper.h>
#include <android/native_activity.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* The native activity interface provided by <android/native_activity.h>
* is based on a set of application-provided callbacks that will be called
* by the Activity's main thread when certain events occur.
*
* This means that each one of this callbacks _should_ _not_ block, or they
* risk having the system force-close the application. This programming
* model is direct, lightweight, but constraining.
*
* The 'threaded_native_app' static library is used to provide a different
* execution model where the application can implement its own main event
* loop in a different thread instead. Here's how it works:
*
* 1/ The application must provide a function named "android_main()" that
* will be called when the activity is created, in a new thread that is
* distinct from the activity's main thread.
*
* 2/ android_main() receives a pointer to a valid "android_app" structure
* that contains references to other important objects, e.g. the
* ANativeActivity obejct instance the application is running in.
*
* 3/ the "android_app" object holds an ALooper instance that already
* listens to two important things:
*
* - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX
* declarations below.
*
* - input events coming from the AInputQueue attached to the activity.
*
* Each of these correspond to an ALooper identifier returned by
* ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT,
* respectively.
*
* Your application can use the same ALooper to listen to additional
* file-descriptors. They can either be callback based, or with return
* identifiers starting with LOOPER_ID_USER.
*
* 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event,
* the returned data will point to an android_poll_source structure. You
* can call the process() function on it, and fill in android_app->onAppCmd
* and android_app->onInputEvent to be called for your own processing
* of the event.
*
* Alternatively, you can call the low-level functions to read and process
* the data directly... look at the process_cmd() and process_input()
* implementations in the glue to see how to do this.
*
* See the sample named "native-activity" that comes with the NDK with a
* full usage example. Also look at the JavaDoc of NativeActivity.
*/
struct android_app;
/**
* Data associated with an ALooper fd that will be returned as the "outData"
* when that source has data ready.
*/
struct android_poll_source {
/* // The identifier of this source. May be LOOPER_ID_MAIN or */
/* // LOOPER_ID_INPUT. */
int32_t id;
/* // The android_app this ident is associated with. */
struct android_app* app;
/* // Function to call to perform the standard processing of data from */
/* // this source. */
void (*process)(struct android_app* app, struct android_poll_source* source);
};
/**
* This is the interface for the standard glue code of a threaded
* application. In this model, the application's code is running
* in its own thread separate from the main thread of the process.
* It is not required that this thread be associated with the Java
* VM, although it will need to be in order to make JNI calls any
* Java objects.
*/
struct android_app {
/* // The application can place a pointer to its own state object */
/* // here if it likes. */
void* userData;
/* // Fill this in with the function to process main app commands (APP_CMD_*) */
void (*onAppCmd)(struct android_app* app, int32_t cmd);
/* // Fill this in with the function to process input events. At this point */
/* // the event has already been pre-dispatched, and it will be finished upon */
/* // return. Return 1 if you have handled the event, 0 for any default */
/* // dispatching. */
int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event);
/* // The ANativeActivity object instance that this app is running in. */
ANativeActivity* activity;
/* // The current configuration the app is running in. */
AConfiguration* config;
/* // This is the last instance's saved state, as provided at creation time. */
/* // It is NULL if there was no state. You can use this as you need; the */
/* // memory will remain around until you call android_app_exec_cmd() for */
/* // APP_CMD_RESUME, at which point it will be freed and savedState set to NULL. */
/* // These variables should only be changed when processing a APP_CMD_SAVE_STATE, */
/* // at which point they will be initialized to NULL and you can malloc your */
/* // state and place the information here. In that case the memory will be */
/* // freed for you later. */
void* savedState;
size_t savedStateSize;
/* // The ALooper associated with the app's thread. */
ALooper* looper;
/* // When non-NULL, this is the input queue from which the app will */
/* // receive user input events. */
AInputQueue* inputQueue;
/* // When non-NULL, this is the window surface that the app can draw in. */
ANativeWindow* window;
/* // Current content rectangle of the window; this is the area where the */
/* // window's content should be placed to be seen by the user. */
ARect contentRect;
/* // Current state of the app's activity. May be either APP_CMD_START, */
/* // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. */
int activityState;
/* // This is non-zero when the application's NativeActivity is being */
/* // destroyed and waiting for the app thread to complete. */
int destroyRequested;
/* // ------------------------------------------------- */
/* // Below are "private" implementation of the glue code. */
pthread_mutex_t mutex;
pthread_cond_t cond;
int msgread;
int msgwrite;
pthread_t thread;
struct android_poll_source cmdPollSource;
struct android_poll_source inputPollSource;
int running;
int stateSaved;
int destroyed;
int redrawNeeded;
AInputQueue* pendingInputQueue;
ANativeWindow* pendingWindow;
ARect pendingContentRect;
};
enum {
/**
* Looper data ID of commands coming from the app's main thread, which
* is returned as an identifier from ALooper_pollOnce(). The data for this
* identifier is a pointer to an android_poll_source structure.
* These can be retrieved and processed with android_app_read_cmd()
* and android_app_exec_cmd().
*/
LOOPER_ID_MAIN = 1,
/**
* Looper data ID of events coming from the AInputQueue of the
* application's window, which is returned as an identifier from
* ALooper_pollOnce(). The data for this identifier is a pointer to an
* android_poll_source structure. These can be read via the inputQueue
* object of android_app.
*/
LOOPER_ID_INPUT = 2,
/**
* Start of user-defined ALooper identifiers.
*/
LOOPER_ID_USER = 3
};
enum {
/**
* Command from main thread: the AInputQueue has changed. Upon processing
* this command, android_app->inputQueue will be updated to the new queue
* (or NULL).
*/
APP_CMD_INPUT_CHANGED,
/**
* Command from main thread: a new ANativeWindow is ready for use. Upon
* receiving this command, android_app->window will contain the new window
* surface.
*/
APP_CMD_INIT_WINDOW,
/**
* Command from main thread: the existing ANativeWindow needs to be
* terminated. Upon receiving this command, android_app->window still
* contains the existing window; after calling android_app_exec_cmd
* it will be set to NULL.
*/
APP_CMD_TERM_WINDOW,
/**
* Command from main thread: the current ANativeWindow has been resized.
* Please redraw with its new size.
*/
APP_CMD_WINDOW_RESIZED,
/**
* Command from main thread: the system needs that the current ANativeWindow
* be redrawn. You should redraw the window before handing this to
* android_app_exec_cmd() in order to avoid transient drawing glitches.
*/
APP_CMD_WINDOW_REDRAW_NEEDED,
/**
* Command from main thread: the content area of the window has changed,
* such as from the soft input window being shown or hidden. You can
* find the new content rect in android_app::contentRect.
*/
APP_CMD_CONTENT_RECT_CHANGED,
/**
* Command from main thread: the app's activity window has gained
* input focus.
*/
APP_CMD_GAINED_FOCUS,
/**
* Command from main thread: the app's activity window has lost
* input focus.
*/
APP_CMD_LOST_FOCUS,
/**
* Command from main thread: the current device configuration has changed.
*/
APP_CMD_CONFIG_CHANGED,
/**
* Command from main thread: the system is running low on memory.
* Try to reduce your memory use.
*/
APP_CMD_LOW_MEMORY,
/**
* Command from main thread: the app's activity has been started.
*/
APP_CMD_START,
/**
* Command from main thread: the app's activity has been resumed.
*/
APP_CMD_RESUME,
/**
* Command from main thread: the app should generate a new saved state
* for itself, to restore from later if needed. If you have saved state,
* allocate it with malloc and place it in android_app.savedState with
* the size in android_app.savedStateSize. The will be freed for you
* later.
*/
APP_CMD_SAVE_STATE,
/**
* Command from main thread: the app's activity has been paused.
*/
APP_CMD_PAUSE,
/**
* Command from main thread: the app's activity has been stopped.
*/
APP_CMD_STOP,
/**
* Command from main thread: the app's activity is being destroyed,
* and waiting for the app thread to clean up and exit before proceeding.
*/
APP_CMD_DESTROY
};
/**
* Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next
* app command message.
*/
int8_t android_app_read_cmd(struct android_app* android_app);
/**
* Call with the command returned by android_app_read_cmd() to do the
* initial pre-processing of the given command. You can perform your own
* actions for the command after calling this function.
*/
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd);
/**
* Call with the command returned by android_app_read_cmd() to do the
* final post-processing of the given command. You must have done your own
* actions for the command before calling this function.
*/
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd);
/**
* Dummy function you can call to ensure glue code isn't stripped.
*/
void app_dummy();
/**
* This is the function that application code must implement, representing
* the main entry to the app.
*/
extern void android_main(struct android_app* app);
/* static */void android_app_write_cmd(struct android_app* android_app, int8_t cmd);
#ifdef __cplusplus
}
#endif
#endif /* _ANDROID_NATIVE_APP_GLUE_H */

View File

@ -0,0 +1,107 @@
/*
* fg_init_blackberry.c
*
* Various freeglut initialization functions.
*
* Copyright (C) 2012 Sylvain Beucler
* Copyright (C) 2013 Vincent Simonetti
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "fg_internal.h"
#include "fg_init.h"
#include "egl/fg_init_egl.h"
#include <bps/bps.h>
#include <screen/screen.h>
void fgPlatformInitialize()
{
bps_initialize();
fghPlatformInitializeEGL();
/* Prepare for screen events */
fgDisplay.pDisplay.event = NULL;
fgDisplay.pDisplay.screenContext = NULL;
/* Create window */
if (screen_create_context(&fgDisplay.pDisplay.screenContext, 0)) {
fgError("Could not create screen context");
return;
}
/* Get screen size */
int displayCount;
screen_display_t* displays;
int vals[2];
if(screen_get_context_property_iv(fgDisplay.pDisplay.screenContext, SCREEN_PROPERTY_DISPLAY_COUNT, &displayCount)) {
fgWarning("Could not get display count. Screen size not determined and will be left at default values");
} else if(displayCount >= 1) {
displays = (screen_display_t*)calloc(displayCount, sizeof(screen_display_t));
if(screen_get_context_property_pv(fgDisplay.pDisplay.screenContext, SCREEN_PROPERTY_DISPLAYS, (void**)displays)) {
fgWarning("Could not get displays. Screen size not determined and will be left at default values");
} else {
/* We only care about the first one, which is the device display */
if(screen_get_display_property_iv(displays[0], SCREEN_PROPERTY_SIZE, vals)) {
fgWarning("Could not get display size. Values will be left at default");
} else {
if(screen_get_display_property_iv(displays[0], SCREEN_PROPERTY_ROTATION, &displayCount) || (displayCount == 0 || displayCount == 180)) {
fgDisplay.ScreenWidth = vals[0];
fgDisplay.ScreenHeight = vals[1];
} else {
fgDisplay.ScreenWidth = vals[1];
fgDisplay.ScreenHeight = vals[0];
}
}
if(screen_get_display_property_iv(displays[0], SCREEN_PROPERTY_PHYSICAL_SIZE, vals)) {
fgWarning("Could not get physical display size. Values will be left at default");
} else {
fgDisplay.ScreenWidthMM = vals[0];
fgDisplay.ScreenHeightMM = vals[1];
}
}
free(displays);
}
/* Get start time */
fgState.Time = fgSystemTime();
fgState.Initialised = GL_TRUE;
}
void fgPlatformCloseDisplay()
{
fghPlatformCloseDisplayEGL();
screen_destroy_context(fgDisplay.pDisplay.screenContext);
fgDisplay.pDisplay.screenContext = NULL;
bps_shutdown();
}
/**
* Close joystick and serial input devices
*/
void fgPlatformDeinitialiseInputDevices ( void )
{
fghCloseInputDevices ();
fgState.JoysticksInitialised = GL_FALSE;
fgState.InputDevsInitialised = GL_FALSE;
}

View File

@ -0,0 +1,134 @@
/*
* fg_internal_blackberry.h
*
* The freeglut library private include file.
*
* Copyright (C) 2012 Sylvain Beucler
* Copyright (C) 2013 Vincent Simonetti
*
* 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
* PAWEL W. OLSZTA 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.
*/
#ifndef FREEGLUT_INTERNAL_BLACKBERRY_H
#define FREEGLUT_INTERNAL_BLACKBERRY_H
//Minor modified version of fg_internal_android.h
/* -- PLATFORM-SPECIFIC INCLUDES ------------------------------------------- */
/* BlackBerry OpenGL ES is accessed through EGL */
#include "egl/fg_internal_egl.h"
#include <screen/screen.h>
#include <bps/event.h>
#include <bps/navigator.h>
/* -- GLOBAL TYPE DEFINITIONS ---------------------------------------------- */
/* The structure used by display initialization in fg_init.c */
typedef struct tagSFG_PlatformDisplay SFG_PlatformDisplay;
struct tagSFG_PlatformDisplay
{
struct tagSFG_PlatformDisplayEGL egl;
screen_context_t screenContext;
bps_event_t* event;
EGLNativeWindowType single_native_window;
};
typedef struct tagSFG_PlatformContext SFG_PlatformContext;
/* SFG_PlatformContext is used for SFG_Window.Window */
struct tagSFG_PlatformContext
{
struct tagSFG_PlatformContextEGL egl;
};
/**
* Virtual PAD (spots on touchscreen that simulate keys)
*/
struct vpad_state {
bool on;
bool left;
bool right;
bool up;
bool down;
};
struct touchscreen {
struct vpad_state vpad;
bool in_mmotion;
};
/* -- INPUT DEFINITIONS ---------------------------------------------------- */
#define WHEEL_DELTA 120 //This is taken from http://msdn.microsoft.com/en-us/library/windows/desktop/ms646254(v=vs.85).aspx
/* -- JOYSTICK-SPECIFIC STRUCTURES AND TYPES ------------------------------- */
/*
* Initial defines from "js.h" starting around line 33 with the existing "fg_joystick.c"
* interspersed
*/
/*
* We'll put these values in and that should
* allow the code to at least compile when there is
* no support. The JS open routine should error out
* and shut off all the code downstream anyway and if
* the application doesn't use a joystick we'll be fine.
*/
struct JS_DATA_TYPE
{
int buttons;
int x;
int y;
};
#define JS_RETURN (sizeof(struct JS_DATA_TYPE))
/* XXX It might be better to poll the operating system for the numbers of buttons and
* XXX axes and then dynamically allocate the arrays.
*/
#define _JS_MAX_AXES 16
typedef struct tagSFG_PlatformJoystick SFG_PlatformJoystick;
struct tagSFG_PlatformJoystick
{
struct JS_DATA_TYPE js;
char fname [ 128 ];
int fd;
};
/* Window's state description. This structure should be kept portable. */
typedef struct tagSFG_PlatformWindowState SFG_PlatformWindowState;
struct tagSFG_PlatformWindowState
{
int newWidth;
int newHeight;
int originalRotation;
navigator_window_state_t windowState;
GLboolean windowCovered;
int keyboardHeight;
GLboolean keyboardOpen;
};
/* Menu font and color definitions */
#define FREEGLUT_MENU_FONT NULL
#define FREEGLUT_MENU_PEN_FORE_COLORS {0.0f, 0.0f, 0.0f, 1.0f}
#define FREEGLUT_MENU_PEN_BACK_COLORS {0.70f, 0.70f, 0.70f, 1.0f}
#define FREEGLUT_MENU_PEN_HFORE_COLORS {0.0f, 0.0f, 0.0f, 1.0f}
#define FREEGLUT_MENU_PEN_HBACK_COLORS {1.0f, 1.0f, 1.0f, 1.0f}
#endif /* FREEGLUT_INTERNAL_BLACKBERRY_H */

View File

@ -0,0 +1,893 @@
/*
* fg_main_blackberry.c
*
* The BlackBerry-specific windows message processing methods.
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Copied for Platform code by Evan Felix <karcaw at gmail.com>
* Copyright (C) 2012 Sylvain Beucler
* Copyright (C) 2013 Vincent Simonetti
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "fg_internal.h"
#include "egl/fg_window_egl.h"
#ifdef NDEBUG
#define LOGI(...)
#endif
#ifdef __PLAYBOOK__
#include <sys/slog.h>
#ifndef LOGI
#define LOGI(...) ((void)slogf(1337, _SLOG_INFO, __VA_ARGS__))
#endif
#define LOGW(...) ((void)slogf(1337, _SLOG_WARNING, __VA_ARGS__))
#ifndef SLOG2_FA_SIGNED
#define SLOG2_FA_SIGNED(x) (x)
#endif
#else
#include <slog2.h>
#ifndef LOGI
#define LOGI(...) ((void)slog2fa(NULL, 1337, SLOG2_INFO, __VA_ARGS__, SLOG2_FA_END))
#endif
#define LOGW(...) ((void)slog2fa(NULL, 1337, SLOG2_WARNING, __VA_ARGS__, SLOG2_FA_END))
#endif
#include <sys/keycodes.h>
#include <input/screen_helpers.h>
#include <bps/bps.h>
#include <bps/event.h>
#include <bps/screen.h>
#include <bps/navigator.h>
#include <bps/virtualkeyboard.h>
extern void fghOnReshapeNotify(SFG_Window *window, int width, int height, GLboolean forceNotify);
extern void fghOnPositionNotify(SFG_Window *window, int x, int y, GLboolean forceNotify);
extern void fgPlatformFullScreenToggle( SFG_Window *win );
extern void fgPlatformPositionWindow( SFG_Window *window, int x, int y );
extern void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height );
extern void fgPlatformPushWindow( SFG_Window *window );
extern void fgPlatformPopWindow( SFG_Window *window );
extern void fgPlatformHideWindow( SFG_Window *window );
extern void fgPlatformIconifyWindow( SFG_Window *window );
extern void fgPlatformShowWindow( SFG_Window *window );
extern void fgPlatformMainLoopPostWork ( void );
extern void fgPlatformRotateWindow( SFG_Window *window, int rotation );
extern void fgPlatformFlushCommands ( void );
static struct touchscreen touchscreen;
#define ESCAPE_BUTTON_KEY 0x001B
unsigned int key_special(int qnxKeycode)
{
switch(qnxKeycode) {
case KEYCODE_F1:
return GLUT_KEY_F1;
case KEYCODE_F2:
return GLUT_KEY_F2;
case KEYCODE_F3:
return GLUT_KEY_F3;
case KEYCODE_F4:
return GLUT_KEY_F4;
case KEYCODE_F5:
return GLUT_KEY_F5;
case KEYCODE_F6:
return GLUT_KEY_F6;
case KEYCODE_F7:
return GLUT_KEY_F7;
case KEYCODE_F8:
return GLUT_KEY_F8;
case KEYCODE_F9:
return GLUT_KEY_F9;
case KEYCODE_F10:
return GLUT_KEY_F10;
case KEYCODE_F11:
return GLUT_KEY_F11;
case KEYCODE_F12:
return GLUT_KEY_F12;
case KEYCODE_PG_UP:
return GLUT_KEY_PAGE_UP;
case KEYCODE_PG_DOWN:
return GLUT_KEY_PAGE_DOWN;
case KEYCODE_HOME:
return GLUT_KEY_HOME;
case KEYCODE_END:
return GLUT_KEY_END;
case KEYCODE_INSERT:
return GLUT_KEY_INSERT;
case KEYCODE_UP:
//case KEYCODE_KP_UP:
return GLUT_KEY_UP;
case KEYCODE_DOWN:
//case KEYCODE_KP_DOWN:
return GLUT_KEY_DOWN;
case KEYCODE_LEFT:
//case KEYCODE_KP_LEFT:
return GLUT_KEY_LEFT;
case KEYCODE_RIGHT:
//case KEYCODE_KP_RIGHT:
return GLUT_KEY_RIGHT;
case KEYCODE_NUM_LOCK:
return GLUT_KEY_NUM_LOCK;
case KEYCODE_LEFT_ALT:
return GLUT_KEY_ALT_L;
case KEYCODE_RIGHT_ALT:
return GLUT_KEY_ALT_R;
case KEYCODE_LEFT_SHIFT:
return GLUT_KEY_SHIFT_L;
case KEYCODE_RIGHT_SHIFT:
return GLUT_KEY_SHIFT_R;
case KEYCODE_LEFT_CTRL:
return GLUT_KEY_CTRL_L;
case KEYCODE_RIGHT_CTRL:
return GLUT_KEY_CTRL_R;
}
return 0;
}
unsigned char key_ascii(int qnxKeycode)
{
if (qnxKeycode >= KEYCODE_PC_KEYS && qnxKeycode <= UNICODE_PRIVATE_USE_AREA_LAST) {
switch (qnxKeycode) {
case KEYCODE_BACKSPACE:
return 0x0008;
case KEYCODE_TAB:
return 0x0009;
case KEYCODE_KP_ENTER:
case KEYCODE_RETURN:
return 0x000A;
case KEYCODE_ESCAPE:
return ESCAPE_BUTTON_KEY;
}
}
return qnxKeycode;
}
//From fg_main_x11
fg_time_t fgPlatformSystemTime ( void )
{
#ifdef CLOCK_MONOTONIC
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
return now.tv_nsec/1000000 + now.tv_sec*1000;
#elif defined(HAVE_GETTIMEOFDAY)
struct timeval now;
gettimeofday( &now, NULL );
return now.tv_usec/1000 + now.tv_sec*1000;
#endif
}
/*
* Does the magic required to relinquish the CPU until something interesting
* happens.
*/
void fgPlatformSleepForEvents( fg_time_t msec )
{
if(fgStructure.CurrentWindow && fgDisplay.pDisplay.event == NULL &&
bps_get_event(&fgDisplay.pDisplay.event, (int)msec) != BPS_SUCCESS) {
LOGW("BPS couldn't get event");
}
}
void handle_left_mouse(int x, int y, int height, int eventType, SFG_Window* window)
{
bool handled = false;
/* Virtual arrows PAD */
/* Don't interfere with existing mouse move event */
if (!touchscreen.in_mmotion) {
struct vpad_state prev_vpad = touchscreen.vpad;
touchscreen.vpad.left = touchscreen.vpad.right = touchscreen.vpad.up = touchscreen.vpad.down = false;
if (eventType == SCREEN_EVENT_MTOUCH_TOUCH || eventType == SCREEN_EVENT_MTOUCH_MOVE) {
if ((x > 0 && x < 100) && (y > (height - 100) && y < height))
{
touchscreen.vpad.left = true;
}
if ((x > 200 && x < 300) && (y > (height - 100) && y < height))
{
touchscreen.vpad.right = true;
}
if ((x > 100 && x < 200) && (y > (height - 100) && y < height))
{
touchscreen.vpad.down = true;
}
if ((x > 100 && x < 200) && (y > (height - 200) && y < (height - 100)))
{
touchscreen.vpad.up = true;
}
}
if (eventType == SCREEN_EVENT_MTOUCH_TOUCH &&
(touchscreen.vpad.left || touchscreen.vpad.right || touchscreen.vpad.down || touchscreen.vpad.up)) {
touchscreen.vpad.on = true;
}
if (eventType == SCREEN_EVENT_MTOUCH_RELEASE) {
touchscreen.vpad.on = false;
}
if (prev_vpad.left != touchscreen.vpad.left
|| prev_vpad.right != touchscreen.vpad.right
|| prev_vpad.up != touchscreen.vpad.up
|| prev_vpad.down != touchscreen.vpad.down
|| prev_vpad.on != touchscreen.vpad.on) {
if (FETCH_WCB(*window, Special)) {
if (prev_vpad.left == false && touchscreen.vpad.left == true) {
INVOKE_WCB(*window, Special, (GLUT_KEY_LEFT, x, y));
}
else if (prev_vpad.right == false && touchscreen.vpad.right == true) {
INVOKE_WCB(*window, Special, (GLUT_KEY_RIGHT, x, y));
}
else if (prev_vpad.up == false && touchscreen.vpad.up == true) {
INVOKE_WCB(*window, Special, (GLUT_KEY_UP, x, y));
}
else if (prev_vpad.down == false && touchscreen.vpad.down == true) {
INVOKE_WCB(*window, Special, (GLUT_KEY_DOWN, x, y));
}
}
if (FETCH_WCB(*window, SpecialUp)) {
if (prev_vpad.left == true && touchscreen.vpad.left == false) {
INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_LEFT, x, y));
}
if (prev_vpad.right == true && touchscreen.vpad.right == false) {
INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_RIGHT, x, y));
}
if (prev_vpad.up == true && touchscreen.vpad.up == false) {
INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_UP, x, y));
}
if (prev_vpad.down == true && touchscreen.vpad.down == false) {
INVOKE_WCB(*window, SpecialUp, (GLUT_KEY_DOWN, x, y));
}
}
handled = true;
}
}
/* Normal mouse events */
if (!handled && !touchscreen.vpad.on) {
window->State.MouseX = x;
window->State.MouseY = y;
if(eventType == SCREEN_EVENT_MTOUCH_MOVE) {
INVOKE_WCB(*window, Motion, (x, y));
} else if(FETCH_WCB(*window, Mouse)) {
touchscreen.in_mmotion = eventType == SCREEN_EVENT_MTOUCH_TOUCH;
int glutTouchType = eventType == SCREEN_EVENT_MTOUCH_TOUCH ? GLUT_DOWN : GLUT_UP;
INVOKE_WCB(*window, Mouse, (GLUT_LEFT_BUTTON, glutTouchType, x, y));
}
}
}
/*
* Determine a GLUT modifier mask based on BlackBerry modifier info.
*/
int fgPlatformGetModifiers (int mod)
{
return (((mod & KEYMOD_SHIFT) ? GLUT_ACTIVE_SHIFT : 0) |
((mod & KEYMOD_CTRL) ? GLUT_ACTIVE_CTRL : 0) |
((mod & KEYMOD_ALT) ? GLUT_ACTIVE_ALT : 0));
}
void fgPlatformHandleKeyboardHeight(SFG_Window* window, int height)
{
int size[2];
int screenHeight;
int nScreenHeight = -1;
screenHeight = glutGet(GLUT_WINDOW_HEIGHT); //Using this takes rotation into account
if(height == 0) {
nScreenHeight = screenHeight;
}
else if(!screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_POSITION, size)) {
/* Calculate the new screen size */ //XXX Make sure to use display size instead of screen size
nScreenHeight = ((size[1] + screenHeight) - height) - size[1];
}
if(nScreenHeight != -1) {
/* If nScreenHeight is less then zero then window is covered. If nScreenHeight == height, then no change in size. Else, change in size */
int screenWidth = glutGet(GLUT_WINDOW_WIDTH);
if(nScreenHeight < 0) {
LOGI("fgPlatformHandleKeyboardHeight: Covered window state");
window->State.Visible = GL_FALSE;
window->State.pWState.windowCovered = GL_TRUE;
INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_COVERED));
fghOnReshapeNotify(window, screenWidth, 0, GL_FALSE);
} else {
if(window->State.pWState.windowCovered == GL_TRUE) {
LOGI("fgPlatformHandleKeyboardHeight: Resetting window state");
/* Reset window status if it was previously covered */
switch(window->State.pWState.windowState) {
case NAVIGATOR_WINDOW_FULLSCREEN:
window->State.Visible = GL_TRUE;
INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_RETAINED));
break;
case NAVIGATOR_WINDOW_THUMBNAIL:
window->State.Visible = GL_TRUE;
INVOKE_WCB(*window, WindowStatus, (GLUT_PARTIALLY_RETAINED));
break;
case NAVIGATOR_WINDOW_INVISIBLE:
window->State.Visible = GL_FALSE;
INVOKE_WCB(*window, WindowStatus, (GLUT_HIDDEN));
break;
}
window->State.pWState.windowCovered = GL_FALSE;
}
fghOnReshapeNotify(window, screenWidth, nScreenHeight, GL_FALSE);
}
}
}
void fgPlatformProcessSingleEvent ( void )
{
if(fgStructure.CurrentWindow == NULL) {
//XXX Is this right? Would this just cause a whole lot of busy looping while we wait for events?
LOGW("fgPlatformProcessSingleEvent: Missing current window. Skipping event processing");
return;
}
if(fgDisplay.pDisplay.event == NULL)
/* Nothing to do */
return;
int domain;
do
{
SFG_Window* window = fgStructure.CurrentWindow;
/* Get the keyboard height before doing anything since we otherwise don't get it until it changes */
if(window->State.pWState.keyboardHeight == 0) {
virtualkeyboard_get_height(&window->State.pWState.keyboardHeight);
}
domain = bps_event_get_domain(fgDisplay.pDisplay.event);
if (domain == screen_get_domain()) {
int eventType;
int mod;
screen_event_t screenEvent = screen_event_get_event(fgDisplay.pDisplay.event);
screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_TYPE, &eventType);
switch (eventType) {
//Mostly from fg_main_android
case SCREEN_EVENT_MTOUCH_TOUCH:
case SCREEN_EVENT_MTOUCH_RELEASE:
case SCREEN_EVENT_MTOUCH_MOVE:
{
mtouch_event_t touchEvent;
screen_get_mtouch_event(screenEvent, &touchEvent, 0);
#ifndef __PLAYBOOK__
screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod);
#else
mod = 0;
#endif
LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_MTOUCH_*: Type: 0x%X, X: %d, Y: %d, Contact Id: %d, Mod: 0x%X", SLOG2_FA_SIGNED(eventType), SLOG2_FA_SIGNED(touchEvent.x), SLOG2_FA_SIGNED(touchEvent.y), SLOG2_FA_SIGNED(touchEvent.contact_id), SLOG2_FA_SIGNED(mod));
/* Remember the current modifiers state so user can query it from their callback */
fgState.Modifiers = fgPlatformGetModifiers(mod);
if(touchEvent.contact_id == 0) {
int size[2];
screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size);
handle_left_mouse(touchEvent.x, touchEvent.y, size[1], eventType, window);
}
//Now handle mutlitouch (adapted from fg_main_windows)
if (eventType == SCREEN_EVENT_MTOUCH_TOUCH) {
INVOKE_WCB( *window, MultiEntry, ( touchEvent.contact_id, GLUT_ENTERED ) );
INVOKE_WCB( *window, MultiButton, ( touchEvent.contact_id, touchEvent.x, touchEvent.y, 0, GLUT_DOWN ) );
} else if (eventType == SCREEN_EVENT_MTOUCH_MOVE) {
INVOKE_WCB( *window, MultiMotion, ( touchEvent.contact_id, touchEvent.x, touchEvent.y ) );
//XXX No motion is performed without contact, thus MultiPassive is never used
} else if (eventType == SCREEN_EVENT_MTOUCH_RELEASE) {
INVOKE_WCB( *window, MultiButton, ( touchEvent.contact_id, touchEvent.x, touchEvent.y, 0, GLUT_UP ) );
INVOKE_WCB( *window, MultiEntry, ( touchEvent.contact_id, GLUT_LEFT ) );
}
fgState.Modifiers = INVALID_MODIFIERS;
break;
}
case SCREEN_EVENT_POINTER:
{
//Based off/part taken from GamePlay3d PlatformBlackBerry
static int mouse_pressed = 0;
int buttons;
int position[2];
int wheel;
// A move event will be fired unless a button state changed.
bool move = true;
bool left_move = false;
// This is a mouse move event, it is applicable to a device with a usb mouse or simulator.
screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_BUTTONS, &buttons);
screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_SOURCE_POSITION, position);
#ifndef __PLAYBOOK__
screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_MOUSE_WHEEL, &wheel);
screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod);
#else
wheel = mod = 0;
#endif
int size[2];
screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size);
LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_POINTER: Buttons: 0x%X, X: %d, Y: %d, Wheel: %d, Mod: 0x%X", SLOG2_FA_SIGNED(buttons), SLOG2_FA_SIGNED(position[0]), SLOG2_FA_SIGNED(position[1]), SLOG2_FA_SIGNED(wheel), SLOG2_FA_SIGNED(mod));
//XXX Is multitouch be handled in a good way?
/* Remember the current modifiers state so user can query it from their callback */
fgState.Modifiers = fgPlatformGetModifiers(mod);
// Handle left mouse. Interpret as touch if the left mouse event is not consumed.
if (buttons & SCREEN_LEFT_MOUSE_BUTTON) {
if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON) {
left_move = true;
} else {
move = false;
mouse_pressed |= SCREEN_LEFT_MOUSE_BUTTON;
handle_left_mouse(position[0], position[1], size[1], SCREEN_EVENT_MTOUCH_TOUCH, window);
}
} else if (mouse_pressed & SCREEN_LEFT_MOUSE_BUTTON) {
move = false;
mouse_pressed &= ~SCREEN_LEFT_MOUSE_BUTTON;
handle_left_mouse(position[0], position[1], size[1], SCREEN_EVENT_MTOUCH_RELEASE, window);
}
// Handle right mouse.
if (buttons & SCREEN_RIGHT_MOUSE_BUTTON) {
if ((mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON) == 0) {
move = false;
mouse_pressed |= SCREEN_RIGHT_MOUSE_BUTTON;
INVOKE_WCB(*window, Mouse, (GLUT_RIGHT_BUTTON, GLUT_DOWN, position[0], position[1]));
}
} else if (mouse_pressed & SCREEN_RIGHT_MOUSE_BUTTON) {
move = false;
mouse_pressed &= ~SCREEN_RIGHT_MOUSE_BUTTON;
INVOKE_WCB(*window, Mouse, (GLUT_RIGHT_BUTTON, GLUT_UP, position[0], position[1]));
}
// Handle middle mouse.
if (buttons & SCREEN_MIDDLE_MOUSE_BUTTON) {
if ((mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON) == 0) {
move = false;
mouse_pressed |= SCREEN_MIDDLE_MOUSE_BUTTON;
INVOKE_WCB(*window, Mouse, (GLUT_MIDDLE_BUTTON, GLUT_DOWN, position[0], position[1]));
}
} else if (mouse_pressed & SCREEN_MIDDLE_MOUSE_BUTTON) {
move = false;
mouse_pressed &= ~SCREEN_MIDDLE_MOUSE_BUTTON;
INVOKE_WCB(*window, Mouse, (GLUT_MIDDLE_BUTTON, GLUT_UP, position[0], position[1]));
}
// Fire a move event if none of the buttons changed.
if (left_move || move) {
handle_left_mouse(position[0], position[1], size[1], SCREEN_EVENT_MTOUCH_MOVE, window);
}
if (wheel) {
/* Very slightly modified from fg_main_mswin.
* Because we don't want MouseWheel to be called every. single. time.
* That the action occurs, we mimic the Windows version with "wheel deltas"
* XXX Do we even want this?
* XXX If we want this, it's possible to get horizontal scroll as well.
* XXX -Vertical scroll=wheel 0, horizontal=wheel 1? */
fgState.MouseWheelTicks -= wheel;
if (abs(fgState.MouseWheelTicks) >= WHEEL_DELTA)
{
int wheel_number = 0;
int direction = (fgState.MouseWheelTicks > 0) ? -1 : 1;
if (!FETCH_WCB(*window, MouseWheel) && !FETCH_WCB(*window, Mouse))
break;
//XXX fgSetWindow(window);
while(abs(fgState.MouseWheelTicks) >= WHEEL_DELTA)
{
if (FETCH_WCB(*window, MouseWheel))
INVOKE_WCB(*window, MouseWheel, (wheel_number, direction, window->State.MouseX, window->State.MouseY));
else /* No mouse wheel, call the mouse button callback twice */
{
/*
* Map wheel zero to button 3 and 4; +1 to 3, -1 to 4
* " " one +1 to 5, -1 to 6, ...
*
* XXX The below assumes that you have no more than 3 mouse
* XXX buttons. Sorry.
*/
int button = wheel_number * 2 + 3;
if (direction < 0)
++button;
INVOKE_WCB(*window, Mouse, (button, GLUT_DOWN, window->State.MouseX, window->State.MouseY));
INVOKE_WCB(*window, Mouse, (button, GLUT_UP, window->State.MouseX, window->State.MouseY));
}
fgState.MouseWheelTicks -= WHEEL_DELTA * direction;
}
}
}
fgState.Modifiers = INVALID_MODIFIERS;
break;
}
//Based off fg_main_android
case SCREEN_EVENT_KEYBOARD:
{
int flags;
int value;
screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_FLAGS, &flags);
screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_SYM, &value);
screen_get_event_property_iv(screenEvent, SCREEN_PROPERTY_KEY_MODIFIERS, &mod);
LOGI("fgPlatformProcessSingleEvent: SCREEN_EVENT_KEYBOARD. Flags: 0x%X, Sym: 0x%X, Mod: 0x%X", SLOG2_FA_SIGNED(flags), SLOG2_FA_SIGNED(value), SLOG2_FA_SIGNED(mod));
/* Suppress key repeats if desired. Based off fg_main_mswin */
if ((flags & KEY_REPEAT) == 0 || (fgState.KeyRepeat == GLUT_KEY_REPEAT_OFF && fgStructure.CurrentWindow->State.IgnoreKeyRepeat == GL_TRUE)) {
unsigned int keypress = 0;
unsigned char ascii = 0;
/* Remember the current modifiers state so user can query it from their callback */
fgState.Modifiers = fgPlatformGetModifiers(mod);
/* Process keys */
if ((keypress = key_special(value))) {
if(flags & KEY_DOWN) {
INVOKE_WCB(*window, Special, (keypress, window->State.MouseX, window->State.MouseY));
} else {
INVOKE_WCB(*window, SpecialUp, (keypress, window->State.MouseX, window->State.MouseY));
}
} else if((flags & KEY_SYM_VALID) && (ascii = key_ascii(value))) {
if(flags & KEY_DOWN) {
INVOKE_WCB(*window, Keyboard, (ascii, window->State.MouseX, window->State.MouseY));
} else {
INVOKE_WCB(*window, KeyboardUp, (ascii, window->State.MouseX, window->State.MouseY));
}
} else {
LOGW("fgPlatformProcessSingleEvent: SCREEN_EVENT_KEYBOARD. Unhandled key event");
}
fgState.Modifiers = INVALID_MODIFIERS;
}
break;
}
case SCREEN_EVENT_PROPERTY:
case SCREEN_EVENT_IDLE:
break;
default:
LOGW("fgPlatformProcessSingleEvent: unknown screen event: 0x%X", SLOG2_FA_SIGNED(eventType));
break;
}
} else if (domain == navigator_get_domain()) {
unsigned int eventType = bps_event_get_code(fgDisplay.pDisplay.event);
switch (eventType) {
case NAVIGATOR_WINDOW_STATE:
{
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE");
/* Covered only happens due to keyboard. When the app is minimized, the keyboard is closed.
When the keyboard is open, and the app is fullscreened, the keyboard is also closed.
If a window is covered and the app is minimized, the state will be set and the keyboard event
will adjust the screen size and change window status. */
navigator_window_state_t state = navigator_event_get_window_state(fgDisplay.pDisplay.event);
if(window->State.pWState.windowCovered == GL_FALSE)
{
switch (state)
{
case NAVIGATOR_WINDOW_FULLSCREEN:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_FULLSCREEN");
window->State.Visible = GL_TRUE;
INVOKE_WCB(*window, WindowStatus, (GLUT_FULLY_RETAINED));
break;
case NAVIGATOR_WINDOW_THUMBNAIL:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_THUMBNAIL");
window->State.Visible = GL_TRUE;
INVOKE_WCB(*window, WindowStatus, (GLUT_PARTIALLY_RETAINED));
break;
case NAVIGATOR_WINDOW_INVISIBLE:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE-NAVIGATOR_WINDOW_INVISIBLE");
window->State.Visible = GL_FALSE;
INVOKE_WCB(*window, WindowStatus, (GLUT_HIDDEN));
break;
default:
LOGW("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_STATE unknown: 0x%X", SLOG2_FA_SIGNED(state));
break;
}
}
window->State.pWState.windowState = state;
break;
}
case NAVIGATOR_EXIT:
{
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_EXIT");
fgPlatformMainLoopPostWork();
/* User closed the application for good, let's kill the window */
SFG_Window* window = fgStructure.CurrentWindow;
if (window != NULL) {
fgDestroyWindow(window);
} else {
LOGW("NAVIGATOR_EXIT: No current window");
}
//XXX Should this be a bit more "forceful" so that it doesn't continue to loop through events?
break;
}
case NAVIGATOR_SWIPE_DOWN:
/* XXX Open app menu */
break;
/* Orientation is a bunch of handshakes.
- First the app get's asked if it wants to rotate (NAVIGATOR_ORIENTATION_CHECK)
- If the app wants to rotate, then it will be told what size it will be after rotate (NAVIGATOR_ORIENTATION_SIZE).
- Once the OS confirms that it's ready to rotate, it tells the app to handle rotation (NAVIGATOR_ORIENTATION).
- Once rotation is complete, the OS tells the app it's done (NAVIGATOR_ORIENTATION_DONE) */
case NAVIGATOR_ORIENTATION_CHECK:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_CHECK");
/* Reset sizes */
window->State.pWState.newWidth = 0;
window->State.pWState.newHeight = 0;
#ifdef __PLAYBOOK__
/* On rotation, the keyboard is closed. This prevents two resize calls */
window->State.pWState.keyboardOpen = GL_FALSE;
#endif
/* Notify that we want to rotate */
navigator_orientation_check_response(fgDisplay.pDisplay.event, true);
break;
case NAVIGATOR_ORIENTATION:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION");
/* NAVIGATOR_ORIENTATION occurs before NAVIGATOR_KEYBOARD_POSITION */
/* Rotate and resize the window */
fgPlatformRotateWindow(window, navigator_event_get_orientation_angle(fgDisplay.pDisplay.event));
fgPlatformFlushCommands();
#ifdef __PLAYBOOK__
/* PlayBook doesn't indicate what the new size will be, so we need to retrieve it from the window itself */
window->State.pWState.newWidth = glutGet(GLUT_WINDOW_WIDTH);
window->State.pWState.newHeight = glutGet(GLUT_WINDOW_HEIGHT);
fghOnReshapeNotify(window, window->State.pWState.newWidth, window->State.pWState.newHeight, GL_FALSE);
#else
if(window->State.pWState.keyboardOpen == GL_FALSE) {
/* On rotation, if the keyboard is open, it will get the keyboard resize events anyway. Otherwise, handle the resize. */
fghOnReshapeNotify(window, window->State.pWState.newWidth, window->State.pWState.newHeight, GL_FALSE);
}
#endif
/* Reset sizes */
window->State.pWState.newWidth = 0;
window->State.pWState.newHeight = 0;
/* Done rotating */
navigator_done_orientation(fgDisplay.pDisplay.event);
break;
case NAVIGATOR_BACK:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_BACK");
INVOKE_WCB(*window, Keyboard, (ESCAPE_BUTTON_KEY, window->State.MouseX, window->State.MouseY));
INVOKE_WCB(*window, KeyboardUp, (ESCAPE_BUTTON_KEY, window->State.MouseX, window->State.MouseY));
break;
case NAVIGATOR_WINDOW_ACTIVE:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_ACTIVE");
INVOKE_WCB(*window, AppStatus, (GLUT_APPSTATUS_RESUME));
break;
case NAVIGATOR_WINDOW_INACTIVE:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_WINDOW_INACTIVE");
INVOKE_WCB(*window, AppStatus, (GLUT_APPSTATUS_PAUSE));
break;
case NAVIGATOR_ORIENTATION_DONE:
case NAVIGATOR_ORIENTATION_RESULT:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_DONE/NAVIGATOR_ORIENTATION_RESULT");
break;
#ifndef __PLAYBOOK__
case NAVIGATOR_KEYBOARD_STATE:
case NAVIGATOR_KEYBOARD_POSITION:
/* See virtual keyboard handling for info on why this is not used. */
break;
case NAVIGATOR_DEVICE_LOCK_STATE:
break;
case NAVIGATOR_WINDOW_COVER:
case NAVIGATOR_WINDOW_COVER_ENTER:
case NAVIGATOR_WINDOW_COVER_EXIT:
/* BlackBerry specific. Let app status and window status take care of everything */
break;
case NAVIGATOR_APP_STATE:
/* Can do the same as NAVIGATOR_WINDOW_ACTIVE/NAVIGATOR_WINDOW_INACTIVE but
seems like it doesn't work when the app comes to the foreground. Might be a bug */
break;
case NAVIGATOR_ORIENTATION_SIZE:
LOGI("fgPlatformProcessSingleEvent: NAVIGATOR_ORIENTATION_SIZE");
/* Get new window size */
window->State.pWState.newWidth = navigator_event_get_orientation_size_width(fgDisplay.pDisplay.event);
window->State.pWState.newHeight = navigator_event_get_orientation_size_height(fgDisplay.pDisplay.event);
break;
#endif
case 0: //Doesn't exist in header, but shows up when keyboard shows and resizes
case NAVIGATOR_OTHER:
break;
default:
LOGW("fgPlatformProcessSingleEvent: unknown navigator event: 0x%X", SLOG2_FA_SIGNED(eventType));
break;
}
}
/*
* BlackBerry 10 navigator provides keyboard events, but they conflict with how we handle keyboard events.
* Causing multiple reshape messages and can leave window state incorrectly setup.
*/
else if(domain == virtualkeyboard_get_domain()) {
unsigned int eventType = bps_event_get_code(fgDisplay.pDisplay.event);
switch (eventType) {
case VIRTUALKEYBOARD_EVENT_VISIBLE:
LOGI("fgPlatformProcessSingleEvent: VIRTUALKEYBOARD_EVENT_VISIBLE");
if(window->State.pWState.keyboardOpen != GL_TRUE) {
window->State.pWState.keyboardOpen = GL_TRUE;
fgPlatformHandleKeyboardHeight(window, window->State.pWState.keyboardHeight);
}
break;
case VIRTUALKEYBOARD_EVENT_HIDDEN:
LOGI("fgPlatformProcessSingleEvent: VIRTUALKEYBOARD_EVENT_HIDDEN");
if(window->State.pWState.keyboardOpen != GL_FALSE) {
window->State.pWState.keyboardOpen = GL_FALSE;
fgPlatformHandleKeyboardHeight(window, 0);
}
break;
case VIRTUALKEYBOARD_EVENT_INFO:
LOGI("fgPlatformProcessSingleEvent: VIRTUALKEYBOARD_EVENT_INFO");
window->State.pWState.keyboardHeight = virtualkeyboard_event_get_height(fgDisplay.pDisplay.event);
if(window->State.pWState.keyboardOpen == GL_TRUE) {
fgPlatformHandleKeyboardHeight(window, window->State.pWState.keyboardHeight);
}
break;
default:
LOGW("fgPlatformProcessSingleEvent: unknown virtualkeyboard event: 0x%X", eventType);
break;
}
}
} while(bps_get_event(&fgDisplay.pDisplay.event, 1) == BPS_SUCCESS && fgDisplay.pDisplay.event != NULL);
/* Reset event to reduce chances of triggering something */
fgDisplay.pDisplay.event = NULL;
}
void fgPlatformMainLoopPreliminaryWork ( void )
{
LOGI("fgPlatformMainLoopPreliminaryWork");
/* Request navigator events */
navigator_request_events(NAVIGATOR_EXTENDED_DATA);
/* Allow rotation */
navigator_rotation_lock(false);
/* Request keyboard events */
virtualkeyboard_request_events(0);
/* Request window events */
screen_request_events(fgDisplay.pDisplay.screenContext);
}
void fgPlatformMainLoopPostWork ( void )
{
LOGI("fgPlatformMainLoopPostWork");
/* Stop all events */
screen_stop_events(fgDisplay.pDisplay.screenContext);
#ifndef __PLAYBOOK__
navigator_stop_events(0);
#endif
}
/* deal with work list items */
void fgPlatformInitWork(SFG_Window* window)
{
LOGI("fgPlatformInitWork");
/* Position callback, always at 0,0 */
fghOnPositionNotify(window, 0, 0, GL_TRUE);
/* Get window size */
int size[2];
screen_get_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size);
fghOnReshapeNotify(window, size[0], size[1], GL_FALSE);
/* Size gets notified on window creation with size detection in mainloop above
* XXX CHECK: does this messages happen too early like on windows,
* so client code cannot have registered a callback yet and the message
* is thus never received by client?
*/
}
void fgPlatformPosResZordWork(SFG_Window* window, unsigned int workMask)
{
if (workMask & GLUT_FULL_SCREEN_WORK)
fgPlatformFullScreenToggle( window );
if (workMask & GLUT_POSITION_WORK)
fgPlatformPositionWindow( window, window->State.DesiredXpos, window->State.DesiredYpos );
if (workMask & GLUT_SIZE_WORK)
fgPlatformReshapeWindow ( window, window->State.DesiredWidth, window->State.DesiredHeight );
if (workMask & GLUT_ZORDER_WORK)
{
if (window->State.DesiredZOrder < 0)
fgPlatformPushWindow( window );
else
fgPlatformPopWindow( window );
}
}
void fgPlatformVisibilityWork(SFG_Window* window)
{
/* Visibility status of window should get updated in the window message handlers
* For now, none of these functions called below do anything, so don't worry
* about it
*/
SFG_Window *win = window;
switch (window->State.DesiredVisibility)
{
case DesireHiddenState:
fgPlatformHideWindow( window );
break;
case DesireIconicState:
/* Call on top-level window */
while (win->Parent)
win = win->Parent;
fgPlatformIconifyWindow( win );
break;
case DesireNormalState:
fgPlatformShowWindow( window );
break;
}
}
/* dummy functions, not applicable on blackberry */
void fgPlatformSetColor(int idx, float r, float g, float b)
{
}
float fgPlatformGetColor(int idx, int comp)
{
}
void fgPlatformCopyColormap(int win)
{
}

View File

@ -0,0 +1,144 @@
/*
* fg_state_blackberry.c
*
* BlackBerry-specific freeglut state query methods.
*
* Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.
* Written by John F. Fay, <fayjf@sourceforge.net>
* Copyright (C) 2012 Sylvain Beucler
* Copyright (C) 2013 Vincent Simonetti
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include <stdio.h>
#include <screen/screen.h>
#include "fg_internal.h"
#include "egl/fg_state_egl.h"
//From fg_state_android.c
int fgPlatformGlutDeviceGet ( GLenum eWhat )
{
#ifndef __PLAYBOOK__
int deviceCount, i, value;
screen_device_t* devices;
#endif
switch( eWhat )
{
case GLUT_HAS_KEYBOARD:
/* BlackBerry has a keyboard, though it may be virtual. */
return 1;
case GLUT_HAS_MOUSE:
/* BlackBerry has a touchscreen. Consider it as a mouse since we have no guarantee
that a mouse will be used (in which case it's a simulator). */
return 1 ;
case GLUT_NUM_MOUSE_BUTTONS:
/* BlackBerry has a touchscreen, which we can consider a 1-button mouse at min.
Otherwise check for an actual mouse, else get max touch points. PlayBook does not support this. */
#ifndef __PLAYBOOK__
if(!screen_get_context_property_iv(fgDisplay.pDisplay.screenContext, SCREEN_PROPERTY_DEVICE_COUNT, &deviceCount)) {
devices = (screen_device_t*)calloc(deviceCount, sizeof(screen_device_t));
if(!screen_get_context_property_pv(fgDisplay.pDisplay.screenContext, SCREEN_PROPERTY_DEVICES, (void**)devices)) {
/* Check for a pointer */
for(i = 0; i < deviceCount; i++) {
if(!screen_get_device_property_iv(devices[i], SCREEN_PROPERTY_TYPE, &value) &&
value == SCREEN_EVENT_POINTER &&
!screen_get_device_property_iv(devices[i], SCREEN_PROPERTY_BUTTON_COUNT, &value)) {
free(devices);
return value;
}
}
/* Check for mtouch */
for(i = 0; i < deviceCount; i++) {
if(!screen_get_device_property_iv(devices[i], SCREEN_PROPERTY_TYPE, &value) &&
value == SCREEN_EVENT_MTOUCH_TOUCH &&
!screen_get_device_property_iv(devices[i], SCREEN_PROPERTY_MAXIMUM_TOUCH_ID, &value)) {
free(devices);
return value;
}
}
}
free(devices);
}
#endif
/* Backup, pretend it's a 1-button mouse */
return 1;
default:
fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
break;
}
/* And now -- the failure. */
return -1;
}
int fgPlatformGlutGet ( GLenum eWhat )
{
switch (eWhat) {
/* One full-screen window only */
case GLUT_WINDOW_X:
case GLUT_WINDOW_Y:
case GLUT_WINDOW_BORDER_WIDTH:
case GLUT_WINDOW_HEADER_HEIGHT:
return 0;
case GLUT_WINDOW_WIDTH:
case GLUT_WINDOW_HEIGHT:
{
if ( fgStructure.CurrentWindow == NULL )
return 0;
int size[2];
int orientation;
if ( screen_get_window_property_iv(fgStructure.CurrentWindow->Window.Handle, SCREEN_PROPERTY_BUFFER_SIZE, size) != 0 )
return 0;
if ( screen_get_window_property_iv(fgStructure.CurrentWindow->Window.Handle, SCREEN_PROPERTY_ROTATION, &orientation) != 0 )
return 0;
int orientationDif = abs(orientation - fgStructure.CurrentWindow->State.pWState.originalRotation);
if (orientationDif == 90 || orientationDif == 270) {
/* Swap dim. if screen is rotated */
int tmp = size[0];
size[0] = size[1];
size[1] = tmp;
}
switch ( eWhat )
{
case GLUT_WINDOW_WIDTH:
return size[0];
case GLUT_WINDOW_HEIGHT:
return size[1];
}
break;
}
case GLUT_WINDOW_COLORMAP_SIZE:
/* 0 for RGBA/non-indexed mode */
/* Under BlackBerry and GLES more generally, no indexed-mode */
return 0;
default:
return fghPlatformGlutGetEGL(eWhat);
}
return -1;
}

View File

@ -0,0 +1,43 @@
/*
* fg_structure_blackberry.c
*
* Windows and menus need tree structure
*
* Copyright (C) 2012 Sylvain Beucler
* Copyright (C) 2013 Vincent Simonetti
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "fg_internal.h"
#include "egl/fg_structure_egl.h"
/**
* Initialize default platform-specific fields in SFG_Window
*/
void fgPlatformCreateWindow ( SFG_Window *window )
{
fghPlatformCreateWindowEGL(window);
memset(&(window->State.pWState), 0, sizeof(SFG_PlatformWindowState));
window->State.pWState.windowCovered = GL_FALSE;
#ifdef __PLAYBOOK__
window->State.pWState.keyboardOpen = GL_FALSE;
#endif
}

View File

@ -0,0 +1,327 @@
/*
* fg_window_blackberry.c
*
* Window management methods for BlackBerry
*
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
* Copied for Platform code by Evan Felix <karcaw at gmail.com>
* Copyright (C) 2012 Sylvain Beucler
* Copyright (C) 2013 Vincent Simonetti
*
* 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
* PAWEL W. OLSZTA 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.
*/
#define FREEGLUT_BUILDING_LIB
#include <GL/freeglut.h>
#include "fg_internal.h"
#include "egl/fg_window_egl.h"
#include <sys/pps.h>
/*
* Opens a window. Requires a SFG_Window object created and attached
* to the freeglut structure. OpenGL context is created here.
*/
void fgPlatformOpenWindow( SFG_Window* window, const char* title,
GLboolean positionUse, int x, int y,
GLboolean sizeUse, int w, int h,
GLboolean gameMode, GLboolean isSubWindow )
{
/* TODO: only one full-screen window possible? */
if (fgDisplay.pDisplay.single_native_window != NULL) {
fgWarning("You can't have more than one window on BlackBerry");
return;
}
/* Create window */
screen_window_t sWindow;
if (screen_create_window(&sWindow, fgDisplay.pDisplay.screenContext)) {
fgError("Could not create window");
return;
}
fgDisplay.pDisplay.single_native_window = sWindow;
/* Choose config and screen format */
fghChooseConfig(&window->Window.pContext.egl.Config);
int screenFormat = SCREEN_FORMAT_RGBA8888; //Only SCREEN_FORMAT_RGBA8888 and SCREEN_FORMAT_RGB565 are supported. See fg_window_egl for more info
int configAttri;
#define EGL_QUERY_COMP(att, comp) (eglGetConfigAttrib(fgDisplay.pDisplay.egl.Display, window->Window.pContext.egl.Config, att, &configAttri) == GL_TRUE && (configAttri comp))
if (EGL_QUERY_COMP(EGL_ALPHA_SIZE, <= 0) && EGL_QUERY_COMP(EGL_RED_SIZE, <= 5) &&
EGL_QUERY_COMP(EGL_GREEN_SIZE, <= 6) && EGL_QUERY_COMP(EGL_BLUE_SIZE, <= 5)) {
screenFormat = SCREEN_FORMAT_RGB565;
}
#undef EGL_QUERY_COMP
/* Set window properties */
int orientation = atoi(getenv("ORIENTATION"));
int screenUsage = SCREEN_USAGE_ROTATION;
#ifdef SCREEN_USAGE_OPENGL_ES3
if (fgState.MajorVersion >= 3) {
screenUsage |= SCREEN_USAGE_OPENGL_ES3;
} else
#endif
if (fgState.MajorVersion >= 2) {
screenUsage |= SCREEN_USAGE_OPENGL_ES2;
} else {
screenUsage |= SCREEN_USAGE_OPENGL_ES1;
}
#if !defined(__X86__) && !defined(__PLAYBOOK__)
screenUsage |= SCREEN_USAGE_DISPLAY; // Physical device copy directly into physical display
#endif
if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_FORMAT, &screenFormat)) {
screen_destroy_window(sWindow);
fgError("Could not set window format");
return;
}
if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_USAGE, &screenUsage)) {
screen_destroy_window(sWindow);
fgError("Could not set window usage");
return;
}
int value[2];
/* Uncomment when multiple windows are supported
if(positionUse) {
value[0] = x;
value[1] = y;
if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_POSITION, value)) {
screen_destroy_window(sWindow);
fgError("Could not set window position");
return;
}
}*/
if(sizeUse) {
/* Uncomment when multiple windows are supported
value[0] = w;
value[1] = h;
*/
//TEMP until ^^ is uncommented
if (screen_get_window_property_iv(sWindow, SCREEN_PROPERTY_BUFFER_SIZE, value)) {
screen_destroy_window(sWindow);
fgError("Could not get window mode");
return;
}
} else {
/* From PlatformBlackBerry in GamePlay3d */
screen_display_t display;
if (screen_get_window_property_pv(sWindow, SCREEN_PROPERTY_DISPLAY, (void**)&display)) {
screen_destroy_window(sWindow);
fgError("Could not get window display");
return;
}
screen_display_mode_t displayMode;
if (screen_get_display_property_pv(display, SCREEN_PROPERTY_MODE, (void**)&displayMode)) {
screen_destroy_window(sWindow);
fgError("Could not get display mode");
return;
}
if (screen_get_window_property_iv(sWindow, SCREEN_PROPERTY_BUFFER_SIZE, value)) {
screen_destroy_window(sWindow);
fgError("Could not get window mode");
return;
}
/* Adjust buffer sizes based on rotation */
if ((orientation == 0) || (orientation == 180))
{
if (((displayMode.width > displayMode.height) && (value[0] < value[1])) ||
((displayMode.width < displayMode.height) && (value[0] > value[1])))
{
int tmp = value[1];
value[1] = value[0];
value[0] = tmp;
}
}
else if ((orientation == 90) || (orientation == 270))
{
if (((displayMode.width > displayMode.height) && (value[0] > value[1])) ||
((displayMode.width < displayMode.height) && (value[0] < value[1])))
{
int tmp = value[1];
value[1] = value[0];
value[0] = tmp;
}
}
else
{
screen_destroy_window(sWindow);
fgError("Unexpected rotation angle");
return;
}
}
/* Set rotation if usage allows it */
if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_ROTATION, &orientation)) {
screen_destroy_window(sWindow);
fgError("Could not set window rotation");
return;
}
window->State.pWState.originalRotation = orientation;
/* Set buffer sizes */
if (screen_set_window_property_iv(sWindow, SCREEN_PROPERTY_BUFFER_SIZE, value)) {
screen_destroy_window(sWindow);
fgError("Could not set window buffer size");
return;
}
/* Create window buffers */
if (screen_create_window_buffers(sWindow, (fgState.DisplayMode & GLUT_DOUBLE) ? 2 : 1)) {
screen_destroy_window(sWindow);
fgError("Could not create window buffers");
return;
}
/* Save window and set state */
window->Window.Handle = sWindow;
window->State.WorkMask |= GLUT_INIT_WORK;
window->State.IsFullscreen = GL_TRUE; //XXX Always fullscreen for now
/* Create context */
window->Window.Context = EGL_NO_CONTEXT;
if( fgState.UseCurrentContext == GL_TRUE )
window->Window.Context = eglGetCurrentContext();
if( window->Window.Context == EGL_NO_CONTEXT )
window->Window.Context = fghCreateNewContextEGL(window);
/* Create EGL window */
fghPlatformOpenWindowEGL(window);
window->State.Visible = GL_TRUE;
}
void fgPlatformFlushCommands()
{
if(screen_flush_context(fgDisplay.pDisplay.screenContext, 0)) {
fgWarning("Could not flush screen context");
}
}
void fgPlatformRotateWindow(SFG_Window* window, int rotation)
{
if(screen_set_window_property_iv(window->Window.Handle, SCREEN_PROPERTY_ROTATION, &rotation)) {
fgWarning("Could not set window rotation");
}
}
/*
* Request a window resize
*/
void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height )
{
fprintf(stderr, "fgPlatformReshapeWindow: STUB\n");
}
/*
* Closes a window, destroying the frame and OpenGL context
*/
void fgPlatformCloseWindow( SFG_Window* window )
{
fghPlatformCloseWindowEGL(window);
screen_destroy_window((screen_window_t)window->Window.Handle);
}
/*
* This function makes the specified window visible
*/
void fgPlatformShowWindow( void )
{
fprintf(stderr, "fgPlatformShowWindow: STUB\n");
}
/*
* This function hides the specified window
*/
void fgPlatformHideWindow( SFG_Window *window )
{
fprintf(stderr, "fgPlatformHideWindow: STUB\n");
}
/*
* Iconify the specified window (top-level windows only)
*/
void fgPlatformIconifyWindow( SFG_Window *window )
{
#ifndef __PLAYBOOK__
pps_encoder_t encoder;
pps_encoder_initialize(&encoder, false);
pps_encoder_add_string(&encoder, "msg", "minimizeWindow");
if (navigator_raw_write(pps_encoder_buffer(&encoder), pps_encoder_length(&encoder)) != BPS_SUCCESS) {
fgWarning("Could not iconify window on BlackBerry");
}
pps_encoder_cleanup(&encoder);
#else
fprintf(stderr, "fgPlatformGlutIconifyWindow: STUB\n");
#endif
}
/*
* Set the current window's title
*/
void fgPlatformGlutSetWindowTitle( const char* title )
{
fprintf(stderr, "fgPlatformGlutSetWindowTitle: STUB\n");
}
/*
* Set the current window's iconified title
*/
void fgPlatformGlutSetIconTitle( const char* title )
{
//XXX Possibly a window cover label?
fprintf(stderr, "fgPlatformGlutSetIconTitle: STUB\n");
}
/*
* Change the specified window's position
*/
void fgPlatformPositionWindow( SFG_Window *window, int x, int y )
{
fprintf(stderr, "fgPlatformPositionWindow: STUB\n");
}
/*
* Lowers the specified window (by Z order change)
*/
void fgPlatformPushWindow( SFG_Window *window )
{
fprintf(stderr, "fgPlatformPushWindow: STUB\n");
}
/*
* Raises the specified window (by Z order change)
*/
void fgPlatformPopWindow( SFG_Window *window )
{
fprintf(stderr, "fgPlatformPopWindow: STUB\n");
}
/*
* Toggle the window's full screen state.
*/
void fgPlatformFullScreenToggle( SFG_Window *win )
{
fprintf(stderr, "fgPlatformFullScreenToggle: STUB\n");
}

33
src/egl/fg_display_egl.c Normal file
View File

@ -0,0 +1,33 @@
/*
* fg_display_android.c
*
* Display message posting, context buffer swapping.
*
* Copyright (C) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "fg_internal.h"
void fgPlatformGlutSwapBuffers( SFG_PlatformDisplay *pDisplayPtr, SFG_Window* CurrentWindow )
{
if (!eglSwapBuffers(pDisplayPtr->egl.Display, CurrentWindow->Window.pContext.egl.Surface))
fgError("eglSwapBuffers: error %x\n", eglGetError());
}

32
src/egl/fg_ext_egl.c Normal file
View File

@ -0,0 +1,32 @@
/*
* fg_ext_egl.c
*
* Functions related to OpenGL extensions.
*
* Copyright (c) 2012 Sylvain Beucler
*
* 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
* PAWEL W. OLSZTA 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.
*/
#include <GL/freeglut.h>
#include "../fg_internal.h"
SFG_Proc fgPlatformGetProcAddress( const char *procName )
{
return (SFG_Proc)eglGetProcAddress(procName);
}

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