Use the opengl-framework library for the examples
This commit is contained in:
parent
f84382bbbe
commit
a1bd7f7be9
|
@ -35,7 +35,7 @@ ADD_LIBRARY (
|
|||
|
||||
# If we need to compile the examples
|
||||
IF (COMPILE_EXAMPLES)
|
||||
add_subdirectory(examples/fallingcubes)
|
||||
add_subdirectory(examples/)
|
||||
ENDIF (COMPILE_EXAMPLES)
|
||||
|
||||
# If we need to compile the tests
|
||||
|
|
5
examples/CMakeLists.txt
Normal file
5
examples/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Minimum cmake version required
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
|
||||
add_subdirectory(opengl-framework/)
|
||||
add_subdirectory(fallingcubes/)
|
|
@ -26,38 +26,155 @@
|
|||
// Libraries
|
||||
#include "Box.h"
|
||||
|
||||
// Use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
// Macros
|
||||
#define MEMBER_OFFSET(s,m) ((char *)NULL + (offsetof(s,m)))
|
||||
|
||||
// Initialize static variables
|
||||
openglframework::VertexBufferObject Box::mVBOVertices(GL_ARRAY_BUFFER);
|
||||
openglframework::VertexBufferObject Box::mVBOIndices(GL_ELEMENT_ARRAY_BUFFER);
|
||||
bool Box::areVBOsCreated = false;
|
||||
VertexData Box::mCubeVertices[8] = {
|
||||
{openglframework::Vector3(1,1,1),openglframework::Vector3(1,1,1),openglframework::Color(0,0,1,1)},
|
||||
{openglframework::Vector3(-1,1,1),openglframework::Vector3(-1,1,1),openglframework::Color(0,0,1,1)},
|
||||
{openglframework::Vector3(-1,-1,1),openglframework::Vector3(-1,-1,1),openglframework::Color(0,0,1,1)},
|
||||
{openglframework::Vector3(1,-1,1),openglframework::Vector3(1,-1,1),openglframework::Color(0,0,1,1)},
|
||||
{openglframework::Vector3(1,-1,-1),openglframework::Vector3(1,-1,-1),openglframework::Color(0,0,1,1)},
|
||||
{openglframework::Vector3(-1,-1,-1),openglframework::Vector3(-1,-1,-1),openglframework::Color(0,0,1,1)},
|
||||
{openglframework::Vector3(-1,1,-1),openglframework::Vector3(-1,1,-1),openglframework::Color(0,0,1,1)},
|
||||
{openglframework::Vector3(1,1,-1),openglframework::Vector3(1,1,-1),openglframework::Color(0,0,1,1)}
|
||||
};
|
||||
GLuint Box::mCubeIndices[36] = { 0, 1, 2,
|
||||
2, 3, 0,
|
||||
7, 4, 5,
|
||||
5, 6, 7,
|
||||
6, 5, 2,
|
||||
2, 1, 6,
|
||||
7, 0, 3,
|
||||
3, 4, 7,
|
||||
7, 6, 1,
|
||||
1, 0, 7,
|
||||
3, 2, 5,
|
||||
5, 4, 3};
|
||||
|
||||
// Constructor
|
||||
Box::Box(double size, RigidBody* rigidBody) {
|
||||
mSize = size;
|
||||
mRigidBody = rigidBody;
|
||||
Box::Box(const openglframework::Vector3& size, const openglframework::Vector3 &position,
|
||||
float mass, reactphysics3d::DynamicsWorld* dynamicsWorld)
|
||||
: openglframework::Object3D() {
|
||||
|
||||
// Initialize the size of the box
|
||||
mSize[0] = size.x * 0.5f;
|
||||
mSize[1] = size.y * 0.5f;
|
||||
mSize[2] = size.z * 0.5f;
|
||||
|
||||
// Compute the scaling matrix
|
||||
mScalingMatrix = openglframework::Matrix4(mSize[0], 0, 0, 0,
|
||||
0, mSize[1], 0, 0,
|
||||
0, 0, mSize[2], 0,
|
||||
0, 0, 0, 1);
|
||||
|
||||
// Initialize the position where the cube will be rendered
|
||||
translateWorld(position);
|
||||
|
||||
// Create the collision shape for the rigid body (box shape)
|
||||
mCollisionShape = new rp3d::BoxShape(rp3d::Vector3(mSize[0], mSize[1], mSize[2]));
|
||||
|
||||
// Compute the inertia tensor of the body using its collision shape
|
||||
rp3d::Matrix3x3 inertiaTensor;
|
||||
mCollisionShape->computeLocalInertiaTensor(inertiaTensor, mass);
|
||||
|
||||
// Initial position and orientation of the rigid body
|
||||
rp3d::Vector3 initPosition(position.x, position.y, position.z);
|
||||
rp3d::Quaternion initOrientation = rp3d::Quaternion::identity();
|
||||
rp3d::Transform transform(initPosition, initOrientation);
|
||||
|
||||
// Create a rigid body corresponding to the cube in the dynamics world
|
||||
mRigidBody = dynamicsWorld->createRigidBody(transform, mass, inertiaTensor, mCollisionShape);
|
||||
|
||||
// If the Vertex Buffer object has not been created yet
|
||||
if (!areVBOsCreated) {
|
||||
// Create the Vertex Buffer
|
||||
createVBO();
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Box::~Box() {
|
||||
|
||||
// Destroy the collision shape
|
||||
delete mCollisionShape;
|
||||
}
|
||||
|
||||
// Draw the box
|
||||
void Box::draw() const {
|
||||
// Render the cube at the correct position and with the correct orientation
|
||||
void Box::render(openglframework::Shader& shader) {
|
||||
|
||||
// Bind the shader
|
||||
shader.bind();
|
||||
|
||||
// Set the model to World matrix
|
||||
shader.setMatrix4x4Uniform("modelToWorldMatrix", mTransformMatrix);
|
||||
|
||||
// Bind the vertices VBO
|
||||
mVBOVertices.bind();
|
||||
|
||||
// Enable the vertex, normal and color arrays
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
// Set the arrays pointers
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, position));
|
||||
glNormalPointer(GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, normal));
|
||||
glColorPointer(3, GL_FLOAT, sizeof(VertexData), MEMBER_OFFSET(VertexData, color));
|
||||
|
||||
// Bind the indices VBO
|
||||
mVBOIndices.bind();
|
||||
|
||||
// Draw the geometry of the box
|
||||
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, (char*)NULL);
|
||||
|
||||
// Unbind the VBOs
|
||||
mVBOVertices.unbind();
|
||||
mVBOIndices.unbind();
|
||||
|
||||
// Disable the arrays
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
// Unbind the shader
|
||||
shader.unbind();
|
||||
}
|
||||
|
||||
// Update the transform matrix of the box
|
||||
void Box::updateTransform() {
|
||||
|
||||
// Get the interpolated transform of the rigid body
|
||||
Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
rp3d::Transform transform = mRigidBody->getInterpolatedTransform();
|
||||
|
||||
// Get the corresponding OpenGL matrix
|
||||
float openGLMatrix[16];
|
||||
transform.getOpenGLMatrix(openGLMatrix);
|
||||
// Compute the transform used for rendering the box
|
||||
float matrix[16];
|
||||
transform.getOpenGLMatrix(matrix);
|
||||
openglframework::Matrix4 newMatrix(matrix[0], matrix[4], matrix[8], matrix[12],
|
||||
matrix[1], matrix[5], matrix[9], matrix[13],
|
||||
matrix[2], matrix[6], matrix[10], matrix[14],
|
||||
matrix[3], matrix[7], matrix[11], matrix[15]);
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
// Multiply by the OpenGL transform matrix
|
||||
glMultMatrixf(openGLMatrix);
|
||||
|
||||
// Draw the cube
|
||||
glutSolidCube(mSize);
|
||||
|
||||
glPopMatrix();
|
||||
// Apply the scaling matrix to have the correct box dimensions
|
||||
mTransformMatrix = newMatrix * mScalingMatrix;
|
||||
}
|
||||
|
||||
// Create the Vertex Buffer Objects used to render to box with OpenGL.
|
||||
/// We create two VBOs (one for vertices and one for indices) to render all the boxes
|
||||
/// in the simulation.
|
||||
void Box::createVBO() {
|
||||
|
||||
// Create the VBOs
|
||||
mVBOVertices.create();
|
||||
mVBOIndices.create();
|
||||
|
||||
// Copy the data into the VBOs
|
||||
mVBOVertices.copyDataIntoVBO(sizeof(mCubeVertices), mCubeVertices, GL_STATIC_DRAW);
|
||||
mVBOIndices.copyDataIntoVBO(sizeof(mCubeIndices), mCubeIndices, GL_STATIC_DRAW);
|
||||
|
||||
areVBOsCreated = true;
|
||||
}
|
||||
|
|
|
@ -23,60 +23,89 @@
|
|||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include <reactphysics3d.h>
|
||||
#ifdef APPLE_OS
|
||||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#include <GL/glu.h>
|
||||
#endif
|
||||
#ifdef USE_FREEGLUT
|
||||
#ifdef APPLE_OS
|
||||
#include <OpenGL/freeglut.h>
|
||||
#else
|
||||
#include <GL/freeglut.h>
|
||||
#endif
|
||||
#else
|
||||
#ifdef APPLE_OS
|
||||
#include <GLUT/glut.h>
|
||||
#else
|
||||
#include <GL/glut.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOX_H
|
||||
#define BOX_H
|
||||
#define BOX_H
|
||||
|
||||
/// This class represents a cube box
|
||||
class Box {
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
|
||||
private:
|
||||
// Structure VertexData
|
||||
struct VertexData {
|
||||
|
||||
/// Size of the box
|
||||
double mSize;
|
||||
/// Vertex position
|
||||
openglframework::Vector3 position;
|
||||
|
||||
/// Pointer to the rigid body associated to the box
|
||||
/// Vertex normal
|
||||
openglframework::Vector3 normal;
|
||||
|
||||
// Vertex color
|
||||
openglframework::Color color;
|
||||
};
|
||||
|
||||
// Class Box
|
||||
class Box : public openglframework::Object3D {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// Size of each side of the box
|
||||
float mSize[3];
|
||||
|
||||
/// Rigid body used to simulate the dynamics of the box
|
||||
rp3d::RigidBody* mRigidBody;
|
||||
|
||||
public:
|
||||
/// Collision shape of the rigid body
|
||||
rp3d::BoxShape* mCollisionShape;
|
||||
|
||||
/// Scaling matrix (applied to a cube to obtain the correct box dimensions)
|
||||
openglframework::Matrix4 mScalingMatrix;
|
||||
|
||||
/// Vertex Buffer Object for the vertices data used to render the box with OpenGL
|
||||
static openglframework::VertexBufferObject mVBOVertices;
|
||||
|
||||
/// Vertex Buffer Object for the indices used to render the box with OpenGL
|
||||
static openglframework::VertexBufferObject mVBOIndices;
|
||||
|
||||
/// Vertex data for each vertex of the cube (used to render the box)
|
||||
static VertexData mCubeVertices[8];
|
||||
|
||||
/// Indices of the cube (used to render the box)
|
||||
static GLuint mCubeIndices[36];
|
||||
|
||||
/// True if the VBOs have already been created
|
||||
static bool areVBOsCreated;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Create a Vertex Buffer Object to render to box with OpenGL
|
||||
static void createVBO();
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Box(double size, rp3d::RigidBody* rigidBody);
|
||||
Box(const openglframework::Vector3& size, const openglframework::Vector3& position,
|
||||
float mass, rp3d::DynamicsWorld* dynamicsWorld);
|
||||
|
||||
/// Destructor
|
||||
~Box();
|
||||
|
||||
/// Return the pointer to the rigid body
|
||||
rp3d::RigidBody* getRigidBodyPointer() const;
|
||||
/// Return a pointer to the rigid body of the box
|
||||
rp3d::RigidBody* getRigidBody();
|
||||
|
||||
/// Draw the box
|
||||
void draw() const;
|
||||
/// Update the transform matrix of the box
|
||||
void updateTransform();
|
||||
|
||||
/// Render the cube at the correct position and with the correct orientation
|
||||
void render(openglframework::Shader& shader);
|
||||
};
|
||||
|
||||
// Return the pointer to the rigid body
|
||||
inline rp3d::RigidBody* Box::getRigidBodyPointer() const {
|
||||
// Return a pointer to the rigid body of the box
|
||||
inline rp3d::RigidBody* Box::getRigidBody() {
|
||||
return mRigidBody;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
49
examples/fallingcubes/CMakeLists.txt
Executable file → Normal file
49
examples/fallingcubes/CMakeLists.txt
Executable file → Normal file
|
@ -4,53 +4,14 @@ cmake_minimum_required(VERSION 2.6)
|
|||
# Project configuration
|
||||
PROJECT(FallingCubes)
|
||||
|
||||
# Find Glut or Freeglut
|
||||
FIND_PACKAGE(GLUT)
|
||||
if (NOT GLUT_FOUND)
|
||||
# Find the Freeglut library
|
||||
FIND_PATH(FREEGLUT_INCLUDE_DIR NAMES GL/freeglut.h
|
||||
/usr/include/GL
|
||||
)
|
||||
FIND_LIBRARY(FREEGLUT_LIBRARY NAMES freeglut glut)
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FREEGLUT DEFAULT_MSG FREEGLUT_LIBRARY FREEGLUT_INCLUDE_DIR)
|
||||
IF(FREEGLUT_FOUND)
|
||||
MESSAGE("Freeglut found")
|
||||
SET(FREEGLUT_LIBRARIES ${FREEGLUT_LIBRARY})
|
||||
SET(FREEGLUT_INCLUDE_DIRS ${FREEGLUT_INCLUDE_DIR})
|
||||
else()
|
||||
MESSAGE("Freeglut not found (required to build the examples)")
|
||||
SET(FREEGLUT_LIBRARIES)
|
||||
SET(FREEGLUT_INCLUDE_DIRS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Find OpenGL
|
||||
FIND_PACKAGE(OpenGL)
|
||||
if(OPENGL_FOUND)
|
||||
MESSAGE("OpenGL found")
|
||||
else()
|
||||
MESSAGE("OpenGL not found")
|
||||
endif()
|
||||
# Copy the shaders used for the demo into the build directory
|
||||
FILE(COPY "../opengl-framework/src/shaders/" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/shaders/")
|
||||
|
||||
# Headers
|
||||
if(GLUT_FOUND)
|
||||
INCLUDE_DIRECTORIES(${REACTPHYSICS3D_SOURCE_DIR}/src ${GLUT_INCLUDE_DIR})
|
||||
elseif(FREEGLUT_FOUND)
|
||||
INCLUDE_DIRECTORIES(${REACTPHYSICS3D_SOURCE_DIR}/src ${FREEGLUT_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
# Definitions
|
||||
if (FREEGLUT_FOUND)
|
||||
ADD_DEFINITIONS(-DUSE_FREEGLUT)
|
||||
endif()
|
||||
INCLUDE_DIRECTORIES("../opengl-framework/src/")
|
||||
|
||||
# Create the example executable using the
|
||||
# compiled reactphysics3d static library
|
||||
ADD_EXECUTABLE(fallingcubes main.cpp Box.cpp Box.h)
|
||||
ADD_EXECUTABLE(fallingcubes main.cpp Scene.cpp Scene.h Box.cpp Box.h)
|
||||
|
||||
if(GLUT_FOUND)
|
||||
TARGET_LINK_LIBRARIES(fallingcubes reactphysics3d ${GLUT_LIBRARY} ${OPENGL_LIBRARY})
|
||||
elseif(FREEGLUT_FOUND)
|
||||
TARGET_LINK_LIBRARIES(fallingcubes reactphysics3d ${FREEGLUT_LIBRARY} ${OPENGL_LIBRARY})
|
||||
endif()
|
||||
TARGET_LINK_LIBRARIES(fallingcubes reactphysics3d openglframework)
|
||||
|
|
169
examples/fallingcubes/Scene.cpp
Normal file
169
examples/fallingcubes/Scene.cpp
Normal file
|
@ -0,0 +1,169 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Scene.h"
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Scene::Scene(GlutViewer* viewer) : mViewer(viewer), mLight0(0),
|
||||
mPhongShader("shaders/phong.vert",
|
||||
"shaders/phong.frag"){
|
||||
|
||||
// Move the light 0
|
||||
mLight0.translateWorld(Vector3(7, 15, 15));
|
||||
|
||||
// Compute the radius and the center of the scene
|
||||
float radius = 10.0f;
|
||||
openglframework::Vector3 center(0, 5, 0);
|
||||
|
||||
// Set the center of the scene
|
||||
mViewer->setScenePosition(center, radius);
|
||||
|
||||
// Gravity vector in the dynamics world
|
||||
rp3d::Vector3 gravity(0, -9.81, 0);
|
||||
|
||||
// Time step for the physics simulation
|
||||
rp3d::decimal timeStep = 1.0f / 80.0f;
|
||||
|
||||
// Create the dynamics world for the physics simulation
|
||||
mDynamicsWorld = new rp3d::DynamicsWorld(gravity, timeStep);
|
||||
|
||||
// Create all the cubes of the scene
|
||||
for (int i=0; i<NB_BOXES; i++) {
|
||||
|
||||
// Position of the cubes
|
||||
openglframework::Vector3 position(0, 5 + i * (BOX_SIZE.y + 0.5f), 0);
|
||||
|
||||
// Create a cube and a corresponding rigid in the dynamics world
|
||||
Box* cube = new Box(BOX_SIZE, position , BOX_MASS, mDynamicsWorld);
|
||||
|
||||
// The box is a moving rigid body
|
||||
cube->getRigidBody()->setIsMotionEnabled(true);
|
||||
|
||||
// Set the bouncing factor of the box
|
||||
cube->getRigidBody()->setRestitution(0.4);
|
||||
|
||||
// Add the box the list of box in the scene
|
||||
mBoxes.push_back(cube);
|
||||
}
|
||||
|
||||
// Create the floor
|
||||
openglframework::Vector3 floorPosition(0, 0, 0);
|
||||
mFloor = new Box(FLOOR_SIZE, floorPosition, FLOOR_MASS, mDynamicsWorld);
|
||||
|
||||
// The floor must be a non-moving rigid body
|
||||
mFloor->getRigidBody()->setIsMotionEnabled(false);
|
||||
|
||||
// Set the bouncing factor of the floor
|
||||
mFloor->getRigidBody()->setRestitution(0.3);
|
||||
|
||||
// Start the simulation
|
||||
mDynamicsWorld->start();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Scene::~Scene() {
|
||||
|
||||
// Stop the physics simulation
|
||||
mDynamicsWorld->stop();
|
||||
|
||||
// Destroy the shader
|
||||
mPhongShader.destroy();
|
||||
|
||||
// Destroy all the cubes of the scene
|
||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||
|
||||
// Destroy the corresponding rigid body from the dynamics world
|
||||
mDynamicsWorld->destroyRigidBody((*it)->getRigidBody());
|
||||
|
||||
// Destroy the cube
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
// Destroy the rigid body of the floor
|
||||
mDynamicsWorld->destroyRigidBody(mFloor->getRigidBody());
|
||||
|
||||
// Destroy the floor
|
||||
delete mFloor;
|
||||
|
||||
// Destroy the dynamics world
|
||||
delete mDynamicsWorld;
|
||||
}
|
||||
|
||||
// Take a step for the simulation
|
||||
void Scene::simulate() {
|
||||
|
||||
// Take a simulation step
|
||||
mDynamicsWorld->update();
|
||||
|
||||
// Update the position and orientation of the boxes
|
||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||
|
||||
// Update the transform used for the rendering
|
||||
(*it)->updateTransform();
|
||||
}
|
||||
|
||||
mFloor->updateTransform();
|
||||
}
|
||||
|
||||
// Render the scene
|
||||
void Scene::render() {
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
// Bind the shader
|
||||
mPhongShader.bind();
|
||||
|
||||
// Set the variables of the shader
|
||||
const Camera& camera = mViewer->getCamera();
|
||||
Matrix4 matrixIdentity;
|
||||
matrixIdentity.setToIdentity();
|
||||
mPhongShader.setVector3Uniform("cameraWorldPosition", mViewer->getCamera().getOrigin());
|
||||
mPhongShader.setMatrix4x4Uniform("worldToCameraMatrix", camera.getTransformMatrix().getInverse());
|
||||
mPhongShader.setMatrix4x4Uniform("projectionMatrix", camera.getProjectionMatrix());
|
||||
mPhongShader.setVector3Uniform("lightWorldPosition", mLight0.getOrigin());
|
||||
mPhongShader.setVector3Uniform("lightAmbientColor", Vector3(0.3f, 0.3f, 0.3f));
|
||||
Color& diffCol = mLight0.getDiffuseColor();
|
||||
Color& specCol = mLight0.getSpecularColor();
|
||||
mPhongShader.setVector3Uniform("lightDiffuseColor", Vector3(diffCol.r, diffCol.g, diffCol.b));
|
||||
mPhongShader.setVector3Uniform("lightSpecularColor", Vector3(specCol.r, specCol.g, specCol.b));
|
||||
mPhongShader.setFloatUniform("shininess", 60.0f);
|
||||
|
||||
// Render all the cubes of the scene
|
||||
for (std::vector<Box*>::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it) {
|
||||
(*it)->render(mPhongShader);
|
||||
}
|
||||
|
||||
// Render the floor
|
||||
mFloor->render(mPhongShader);
|
||||
|
||||
// Unbind the shader
|
||||
mPhongShader.unbind();
|
||||
}
|
83
examples/fallingcubes/Scene.h
Normal file
83
examples/fallingcubes/Scene.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/********************************************************************************
|
||||
* ReactPhysics3D physics library, http://code.google.com/p/reactphysics3d/ *
|
||||
* Copyright (c) 2010-2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef SCENE_H
|
||||
#define SCENE_H
|
||||
|
||||
// Libraries
|
||||
#include "openglframework.h"
|
||||
#include "reactphysics3d.h"
|
||||
#include "Box.h"
|
||||
|
||||
// Constants
|
||||
const int NB_BOXES = 10; // Number of boxes in the scene
|
||||
const openglframework::Vector3 BOX_SIZE(2, 2, 2); // Box dimensions in meters
|
||||
const openglframework::Vector3 FLOOR_SIZE(20, 0.5f, 20); // Floor dimensions in meters
|
||||
const float BOX_MASS = 1.0f; // Box mass in kilograms
|
||||
const float FLOOR_MASS = 100.0f; // Floor mass in kilograms
|
||||
|
||||
// Class Scene
|
||||
class Scene {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Pointer to the viewer
|
||||
openglframework::GlutViewer* mViewer;
|
||||
|
||||
// Light 0
|
||||
openglframework::Light mLight0;
|
||||
|
||||
// Phong shader
|
||||
openglframework::Shader mPhongShader;
|
||||
|
||||
/// All the boxes of the scene
|
||||
std::vector<Box*> mBoxes;
|
||||
|
||||
/// Box for the floor
|
||||
Box* mFloor;
|
||||
|
||||
/// Dynamics world used for the physics simulation
|
||||
rp3d::DynamicsWorld* mDynamicsWorld;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
Scene(openglframework::GlutViewer* viewer);
|
||||
|
||||
/// Destructor
|
||||
~Scene();
|
||||
|
||||
/// Take a step for the simulation
|
||||
void simulate();
|
||||
|
||||
/// Render the scene
|
||||
void render();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -24,225 +24,166 @@
|
|||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include <stdlib.h>
|
||||
#include <reactphysics3d.h>
|
||||
#include "Box.h"
|
||||
#include "Scene.h"
|
||||
#include <sstream>
|
||||
|
||||
// Prototypes
|
||||
void init();
|
||||
void display();
|
||||
// Declarations
|
||||
void simulate();
|
||||
void clean();
|
||||
void reshape(int w, int h);
|
||||
void display();
|
||||
void displayFPS();
|
||||
void computeFPS();
|
||||
void reshape(int width, int height);
|
||||
void mouseButton(int button, int state, int x, int y);
|
||||
void mouseMotion(int x, int y);
|
||||
void keyboardSpecial(int key, int x, int y);
|
||||
void init();
|
||||
|
||||
// Use the ReactPhysics3D namespace
|
||||
using namespace reactphysics3d;
|
||||
|
||||
// Constants
|
||||
const double FLOOR_SIZE = 20;
|
||||
const double FLOOR_THICKNESS = 0.02;
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Global variables
|
||||
DynamicsWorld* dynamicsWorld; // Dynamics world
|
||||
Box* boxes[2]; // Falling boxes
|
||||
BoxShape* collisionShapeBox1; // Collision shape of the first box
|
||||
BoxShape* collisionShapeBox2; // Collision shape of the second box
|
||||
BoxShape* collisionShapeFloor; // Collision shape of the floor
|
||||
RigidBody* floorRigidBody; // Rigid body corresponding the floor
|
||||
|
||||
|
||||
// Simulation function
|
||||
void simulate() {
|
||||
|
||||
// Update the physics simulation
|
||||
dynamicsWorld->update();
|
||||
|
||||
// Display the scene
|
||||
display();
|
||||
}
|
||||
GlutViewer* viewer;
|
||||
Scene* scene;
|
||||
int fps;
|
||||
int nbFrames;
|
||||
int currentTime;
|
||||
int previousTime;
|
||||
int width, height;
|
||||
|
||||
// Main function
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
// Initialize GLUT
|
||||
glutInit(&argc, argv);
|
||||
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
|
||||
glutInitWindowSize(800, 600);
|
||||
glutInitWindowPosition(100, 100);
|
||||
glutCreateWindow("ReactPhysics3D Example - Falling Cubes");
|
||||
// Create and initialize the Viewer
|
||||
viewer = new GlutViewer();
|
||||
Vector2 windowsSize = Vector2(800, 600);
|
||||
Vector2 windowsPosition = Vector2(100, 100);
|
||||
width = windowsSize.x;
|
||||
height = windowsSize.y;
|
||||
bool initOK = viewer->init(argc, argv, "ReactPhysics3D Examples - Falling Cubes", windowsSize, windowsPosition);
|
||||
if (!initOK) return 1;
|
||||
|
||||
// Create the scene
|
||||
scene = new Scene(viewer);
|
||||
|
||||
init();
|
||||
|
||||
nbFrames = 0;
|
||||
|
||||
// Glut Idle function that is continuously called
|
||||
glutIdleFunc(simulate);
|
||||
glutDisplayFunc(display);
|
||||
glutReshapeFunc(reshape);
|
||||
glutMouseFunc(mouseButton);
|
||||
glutMotionFunc(mouseMotion);
|
||||
glutSpecialFunc(keyboardSpecial);
|
||||
|
||||
// Glut main looop
|
||||
glutMainLoop();
|
||||
|
||||
// Stop the physics simulation
|
||||
dynamicsWorld->stop();
|
||||
delete viewer;
|
||||
delete scene;
|
||||
|
||||
clean();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Initialization function
|
||||
void init() {
|
||||
// Simulate function
|
||||
void simulate() {
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
// Physics simulation
|
||||
scene->simulate();
|
||||
|
||||
// Light
|
||||
glShadeModel(GL_SMOOTH);
|
||||
GLfloat light_position[] = {5.0f, 5.0f, 5.0f, 1.0f};
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
|
||||
computeFPS();
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// Gravity vector of the physics world
|
||||
Vector3 gravity(0.0, -9.81, 0.0);
|
||||
|
||||
// Timestep of the simulation
|
||||
decimal timeStep = 1.0/60.0;
|
||||
|
||||
// Create the dynamics world
|
||||
dynamicsWorld = new DynamicsWorld(gravity, timeStep);
|
||||
|
||||
// --- Create a falling box with a size of 1m and weight of 3kg --- //
|
||||
|
||||
float size = 1.0f;
|
||||
|
||||
// Initial position and orientation of the box
|
||||
Vector3 positionBox1(-2.0f, 7.0f, 0.0f);
|
||||
Quaternion orientationBox1(0.3, 1.0, 0.8, 0.0);
|
||||
Transform initTransform(positionBox1, orientationBox1);
|
||||
|
||||
// Create a box collision shape for the box (used for collision detection)
|
||||
collisionShapeBox1 = new BoxShape(Vector3(size/2.0f, size/2.0f, size/2.0f));
|
||||
|
||||
// Compute the inertia tensor of the box using the collision shape
|
||||
Matrix3x3 inertiaTensorBox1;
|
||||
float massBox1 = 3.0f;
|
||||
collisionShapeBox1->computeLocalInertiaTensor(inertiaTensorBox1, massBox1);
|
||||
|
||||
// Create the rigid body associated with the box in the dynamics world
|
||||
RigidBody* rigidBody = dynamicsWorld->createRigidBody(initTransform, massBox1,
|
||||
inertiaTensorBox1, collisionShapeBox1);
|
||||
|
||||
// Set the contact velocity restitution factor of the rigid body
|
||||
rigidBody->setRestitution(0.5f);
|
||||
|
||||
// Create the box object (used for display)
|
||||
boxes[0] = new Box(size, rigidBody);
|
||||
|
||||
// --- Create a second falling box with a size of 1.5m and weight of 4.5kg --- //
|
||||
|
||||
size = 1.5;
|
||||
|
||||
// Initial position and orientation of the box
|
||||
Vector3 positionBox2(2.0, 4.0, 0.0);
|
||||
Quaternion orientationBox2(1.0, 1.0, 0.5, 0.0);
|
||||
Transform initTransform2(positionBox2, orientationBox2);
|
||||
|
||||
// Create a box collision shape for the box (used for collision detection)
|
||||
collisionShapeBox2 = new BoxShape(Vector3(size/2.0f, size/2.0f, size/2.0f));
|
||||
|
||||
// Compute the inertia tensor using the collision shape
|
||||
Matrix3x3 inertiaTensorBox2;
|
||||
float massBox2 = 4.5f;
|
||||
collisionShapeBox2->computeLocalInertiaTensor(inertiaTensorBox2, massBox2);
|
||||
|
||||
// Create the rigid body associated with the box in the dynamcis world
|
||||
RigidBody* rigidBody2 = dynamicsWorld->createRigidBody(initTransform2, massBox2,
|
||||
inertiaTensorBox2, collisionShapeBox2);
|
||||
|
||||
// Set the contact velocity restitution factor of the rigid body
|
||||
rigidBody2->setRestitution(0.5);
|
||||
|
||||
// Create the box object (used for display)
|
||||
boxes[1] = new Box(size, rigidBody2);
|
||||
|
||||
// --- Create the rigid body corresponding to the floor --- //
|
||||
|
||||
// Initial position and orientation of the floor
|
||||
Vector3 positionFloor(0.0, 0.0, 0.0);
|
||||
Quaternion orientationFloor(0.0, 1.0, 0.0, 0.0);
|
||||
Transform initTransformFloor(positionFloor, orientationFloor);
|
||||
|
||||
// Create a box collision shape for the floor (used for collision detection)
|
||||
collisionShapeFloor = new BoxShape(Vector3(FLOOR_SIZE, FLOOR_THICKNESS, FLOOR_SIZE));
|
||||
|
||||
// Compute the inertia tensor of the floor using the collision shape
|
||||
float massFloor = 100.0f;
|
||||
rp3d::Matrix3x3 inertiaTensorFloor;
|
||||
collisionShapeFloor->computeLocalInertiaTensor(inertiaTensorFloor, massFloor);
|
||||
|
||||
// Create the rigid body associated with the floor in the dynamcis world
|
||||
floorRigidBody = dynamicsWorld->createRigidBody(initTransformFloor, massFloor,
|
||||
inertiaTensorFloor, collisionShapeFloor);
|
||||
|
||||
// The floor is a rigid body that cannot move
|
||||
floorRigidBody->setIsMotionEnabled(false);
|
||||
|
||||
// Set the contact velocity restitution factor of the floor
|
||||
floorRigidBody->setRestitution(0.5);
|
||||
|
||||
// Start the dynamics simulation
|
||||
dynamicsWorld->start();
|
||||
// Ask GLUT to render the scene
|
||||
glutPostRedisplay ();
|
||||
}
|
||||
|
||||
// Display function
|
||||
void display() {
|
||||
// Initialization
|
||||
void init() {
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Display each falling box of the scene
|
||||
for (int i=0; i<2; i++) {
|
||||
boxes[i]->draw();
|
||||
}
|
||||
|
||||
// Display the plane for the floor
|
||||
glBegin(GL_POLYGON);
|
||||
glNormal3f(0.0, 1.0, 0.0);
|
||||
glVertex3f(-FLOOR_SIZE/2, 0.0, -FLOOR_SIZE/2);
|
||||
glVertex3f(-FLOOR_SIZE/2, 0.0, FLOOR_SIZE/2);
|
||||
glVertex3f(FLOOR_SIZE/2, 0.0, FLOOR_SIZE/2);
|
||||
glVertex3f(FLOOR_SIZE/2, 0.0, -FLOOR_SIZE/2);
|
||||
glEnd();
|
||||
|
||||
glutSwapBuffers();
|
||||
// Define the background color (black)
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
// Reshape function
|
||||
void reshape(int w, int h) {
|
||||
float ratio = ((float)w / h);
|
||||
void reshape(int newWidth, int newHeight) {
|
||||
viewer->reshape(newWidth, newHeight);
|
||||
width = newWidth;
|
||||
height = newHeight;
|
||||
}
|
||||
|
||||
// Called when a mouse button event occurs
|
||||
void mouseButton(int button, int state, int x, int y) {
|
||||
viewer->mouseButtonEvent(button, state, x, y);
|
||||
}
|
||||
|
||||
// Called when a mouse motion event occurs
|
||||
void mouseMotion(int x, int y) {
|
||||
viewer->mouseMotionEvent(x, y);
|
||||
}
|
||||
|
||||
// Called when the user hits a special key on the keyboard
|
||||
void keyboardSpecial(int key, int x, int y) {
|
||||
/*
|
||||
if(key=='0')
|
||||
exit(0);
|
||||
if(key== GLUT_KEY_RIGHT) {
|
||||
*/
|
||||
}
|
||||
|
||||
// Display the scene
|
||||
void display() {
|
||||
|
||||
// Render the scene
|
||||
scene->render();
|
||||
|
||||
// Display the FPS
|
||||
displayFPS();
|
||||
|
||||
// Swap the buffers
|
||||
glutSwapBuffers();
|
||||
|
||||
// Check the OpenGL errors
|
||||
GlutViewer::checkOpenGLErrors();
|
||||
}
|
||||
|
||||
// Compute the FPS
|
||||
void computeFPS() {
|
||||
nbFrames++;
|
||||
|
||||
// Get the number of milliseconds since glutInit called
|
||||
currentTime = glutGet(GLUT_ELAPSED_TIME);
|
||||
|
||||
// Calculate time passed
|
||||
int timeInterval = currentTime - previousTime;
|
||||
|
||||
// Update the FPS counter each second
|
||||
if(timeInterval > 1000){
|
||||
|
||||
// calculate the number of frames per second
|
||||
fps = nbFrames / (timeInterval / 1000.0f);
|
||||
|
||||
// Set time
|
||||
previousTime = currentTime;
|
||||
|
||||
// Reset frame count
|
||||
nbFrames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Display the FPS
|
||||
void displayFPS() {
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glViewport(0, 0, w, h);
|
||||
gluPerspective(45, ratio,1,1000);
|
||||
glOrtho(0, width, height, 0, -1, 1);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(20.0, 4.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
// Clean the memory allocation
|
||||
void clean() {
|
||||
|
||||
// Destroy the rigid bodies from the dynamics world
|
||||
dynamicsWorld->destroyRigidBody(boxes[0]->getRigidBodyPointer());
|
||||
dynamicsWorld->destroyRigidBody(boxes[1]->getRigidBodyPointer());
|
||||
dynamicsWorld->destroyRigidBody(floorRigidBody);
|
||||
|
||||
// Destroy the dynamics world
|
||||
delete dynamicsWorld;
|
||||
|
||||
// Destroy the boxes
|
||||
delete boxes[0];
|
||||
delete boxes[1];
|
||||
|
||||
// Destroy the collision shapes
|
||||
delete collisionShapeBox1;
|
||||
delete collisionShapeBox2;
|
||||
delete collisionShapeFloor;
|
||||
|
||||
glRasterPos2i(10, 20);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
std::stringstream ss;
|
||||
ss << "FPS : " << fps;
|
||||
glutBitmapString(GLUT_BITMAP_HELVETICA_12, (const unsigned char*)ss.str().c_str());
|
||||
}
|
||||
|
|
55
examples/opengl-framework/CMakeLists.txt
Normal file
55
examples/opengl-framework/CMakeLists.txt
Normal file
|
@ -0,0 +1,55 @@
|
|||
# Minimum cmake version required
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
|
||||
# Project configuration
|
||||
PROJECT(OPENGLFRAMEWORK)
|
||||
|
||||
# Where to find the module to find special packages/libraries
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
|
||||
|
||||
# Find OpenGL
|
||||
FIND_PACKAGE(OpenGL REQUIRED)
|
||||
if(OPENGL_FOUND)
|
||||
MESSAGE("OpenGL found")
|
||||
else()
|
||||
MESSAGE("OpenGL not found")
|
||||
endif()
|
||||
|
||||
# Find the GLEW library
|
||||
FIND_PACKAGE(GLEW REQUIRED)
|
||||
if(GLEW_FOUND)
|
||||
MESSAGE("GLEW found")
|
||||
else()
|
||||
MESSAGE("GLEW not found")
|
||||
endif()
|
||||
|
||||
# Find the LIBJPEG library
|
||||
FIND_PACKAGE(JPEG REQUIRED)
|
||||
if(JPEG_FOUND)
|
||||
MESSAGE("LIBJPEG found")
|
||||
else()
|
||||
MESSAGE("LIBJPEG not found")
|
||||
endif()
|
||||
|
||||
# Freeglut
|
||||
add_subdirectory(freeglut)
|
||||
|
||||
# Headers
|
||||
INCLUDE_DIRECTORIES(src freeglut ${JPEG_INCLUDE_DIR})
|
||||
|
||||
# Library configuration
|
||||
file (
|
||||
GLOB_RECURSE
|
||||
OPENGLFRAMEWORK_SOURCES_FILES
|
||||
src/*
|
||||
)
|
||||
|
||||
|
||||
# Require the opengl-framework code to be compiled in a static library
|
||||
ADD_LIBRARY (
|
||||
openglframework
|
||||
STATIC
|
||||
${OPENGLFRAMEWORK_SOURCES_FILES}
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(openglframework ${GLEW_LIBRARIES} ${OPENGL_LIBRARY} freeglut_static)
|
24
examples/opengl-framework/freeglut/CMakeLists.txt
Normal file
24
examples/opengl-framework/freeglut/CMakeLists.txt
Normal file
|
@ -0,0 +1,24 @@
|
|||
add_definitions( -DFREEGLUT_EXPORTS -DFREEGLUT_STATIC -D_CRT_SECURE_NO_WARNINGS )
|
||||
|
||||
if(APPLE)
|
||||
include_directories( /usr/X11/include )
|
||||
endif(APPLE)
|
||||
|
||||
if(UNIX)
|
||||
add_definitions( -D__unix__ -DHAVE_FCNTL_H -DHAVE_GETTIMEOFDAY )
|
||||
endif(UNIX)
|
||||
|
||||
file (
|
||||
GLOB_RECURSE
|
||||
FREEGLUT_SOURCES
|
||||
./*
|
||||
)
|
||||
|
||||
include_directories (
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
.
|
||||
)
|
||||
|
||||
add_library(freeglut_static
|
||||
${FREEGLUT_SOURCES}
|
||||
)
|
27
examples/opengl-framework/freeglut/COPYING.txt
Normal file
27
examples/opengl-framework/freeglut/COPYING.txt
Normal 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.
|
22
examples/opengl-framework/freeglut/GL/freeglut.h
Normal file
22
examples/opengl-framework/freeglut/GL/freeglut.h
Normal 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__ */
|
236
examples/opengl-framework/freeglut/GL/freeglut_ext.h
Normal file
236
examples/opengl-framework/freeglut/GL/freeglut_ext.h
Normal file
|
@ -0,0 +1,236 @@
|
|||
#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
|
||||
|
||||
/*
|
||||
* 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_HEADER_HEIGHT 0x01FB
|
||||
|
||||
#define GLUT_VERSION 0x01FC
|
||||
|
||||
#define GLUT_RENDERING_CONTEXT 0x01FD
|
||||
#define GLUT_DIRECT_RENDERING 0x01FE
|
||||
|
||||
#define GLUT_FULL_SCREEN 0x01FF
|
||||
|
||||
/*
|
||||
* 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 freeglut_state.c
|
||||
*/
|
||||
#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 freeglut_init.c
|
||||
*/
|
||||
#define GLUT_DEBUG 0x0001
|
||||
#define GLUT_FORWARD_COMPATIBLE 0x0002
|
||||
|
||||
|
||||
/*
|
||||
* Flags for glutInitContextProfile, see freeglut_init.c
|
||||
*/
|
||||
#define GLUT_CORE_PROFILE 0x0001
|
||||
#define GLUT_COMPATIBILITY_PROFILE 0x0002
|
||||
|
||||
/*
|
||||
* Process loop function, see freeglut_main.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutMainLoopEvent( void );
|
||||
FGAPI void FGAPIENTRY glutLeaveMainLoop( void );
|
||||
FGAPI void FGAPIENTRY glutExit ( void );
|
||||
|
||||
/*
|
||||
* Window management functions, see freeglut_window.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutFullScreenToggle( void );
|
||||
FGAPI void FGAPIENTRY glutLeaveFullScreen( void );
|
||||
|
||||
/*
|
||||
* Window-specific callback functions, see freeglut_callbacks.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) );
|
||||
FGAPI void FGAPIENTRY glutCloseFunc( void (* callback)( void ) );
|
||||
FGAPI void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) );
|
||||
/* A. Donev: Also a destruction callback for menus */
|
||||
FGAPI void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) );
|
||||
|
||||
/*
|
||||
* State setting and retrieval functions, see freeglut_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 freeglut_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 freeglut_geometry.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutWireRhombicDodecahedron( void );
|
||||
FGAPI void FGAPIENTRY glutSolidRhombicDodecahedron( void );
|
||||
FGAPI void FGAPIENTRY glutWireSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale );
|
||||
FGAPI void FGAPIENTRY glutSolidSierpinskiSponge ( int num_levels, GLdouble offset[3], GLdouble scale );
|
||||
FGAPI void FGAPIENTRY glutWireCylinder( GLdouble radius, GLdouble height, GLint slices, GLint stacks);
|
||||
FGAPI void FGAPIENTRY glutSolidCylinder( GLdouble radius, GLdouble height, GLint slices, GLint stacks);
|
||||
|
||||
/*
|
||||
* Extension functions, see freeglut_ext.c
|
||||
*/
|
||||
typedef void (*GLUTproc)();
|
||||
FGAPI GLUTproc FGAPIENTRY glutGetProcAddress( const char *procName );
|
||||
|
||||
/*
|
||||
* Multi-touch/multi-pointer extensions
|
||||
*/
|
||||
|
||||
#define GLUT_HAS_MULTI 1
|
||||
|
||||
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 freeglut_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 freeglut_init.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutInitContextVersion( int majorVersion, int minorVersion );
|
||||
FGAPI void FGAPIENTRY glutInitContextFlags( int flags );
|
||||
FGAPI void FGAPIENTRY glutInitContextProfile( int profile );
|
||||
|
||||
/* to get the typedef for va_list */
|
||||
#include <stdarg.h>
|
||||
|
||||
FGAPI void FGAPIENTRY glutInitErrorFunc( void (* vError)( const char *fmt, va_list ap ) );
|
||||
FGAPI void FGAPIENTRY glutInitWarningFunc( void (* vWarning)( const char *fmt, va_list ap ) );
|
||||
|
||||
/*
|
||||
* GLUT API macro definitions -- the display mode definitions
|
||||
*/
|
||||
#define GLUT_CAPTIONLESS 0x0400
|
||||
#define GLUT_BORDERLESS 0x0800
|
||||
#define GLUT_SRGB 0x1000
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*** END OF FILE ***/
|
||||
|
||||
#endif /* __FREEGLUT_EXT_H__ */
|
628
examples/opengl-framework/freeglut/GL/freeglut_std.h
Normal file
628
examples/opengl-framework/freeglut/GL/freeglut_std.h
Normal file
|
@ -0,0 +1,628 @@
|
|||
#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
|
||||
# pragma comment (lib, "freeglut_static.lib")
|
||||
# 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
|
||||
# pragma comment (lib, "freeglut.lib")
|
||||
# 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 FREEGLUT_VERSION_2_0 1
|
||||
#define GLUT_XLIB_IMPLEMENTATION 13
|
||||
|
||||
/*
|
||||
* Always include OpenGL and GLU headers
|
||||
*/
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
|
||||
/*
|
||||
* 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 freeglut_main.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutMainLoop( void );
|
||||
|
||||
/*
|
||||
* Window management functions, see freeglut_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-connected functions, see freeglut_display.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutPostWindowRedisplay( int window );
|
||||
FGAPI void FGAPIENTRY glutPostRedisplay( void );
|
||||
FGAPI void FGAPIENTRY glutSwapBuffers( void );
|
||||
|
||||
/*
|
||||
* Mouse cursor functions, see freeglut_cursor.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutWarpPointer( int x, int y );
|
||||
FGAPI void FGAPIENTRY glutSetCursor( int cursor );
|
||||
|
||||
/*
|
||||
* Overlay stuff, see freeglut_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 freeglut_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 freeglut_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 freeglut_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 freeglut_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 freeglut_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 int FGAPIENTRY glutBitmapLength( void* font, const unsigned char* string );
|
||||
FGAPI int FGAPIENTRY glutStrokeLength( void* font, const unsigned char* string );
|
||||
|
||||
/*
|
||||
* Geometry functions, see freeglut_geometry.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutWireCube( GLdouble size );
|
||||
FGAPI void FGAPIENTRY glutSolidCube( GLdouble size );
|
||||
FGAPI void FGAPIENTRY glutWireSphere( GLdouble radius, GLint slices, GLint stacks );
|
||||
FGAPI void FGAPIENTRY glutSolidSphere( GLdouble radius, GLint slices, GLint stacks );
|
||||
FGAPI void FGAPIENTRY glutWireCone( GLdouble base, GLdouble height, GLint slices, GLint stacks );
|
||||
FGAPI void FGAPIENTRY glutSolidCone( GLdouble base, GLdouble height, GLint slices, GLint stacks );
|
||||
|
||||
FGAPI void FGAPIENTRY glutWireTorus( GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings );
|
||||
FGAPI void FGAPIENTRY glutSolidTorus( GLdouble innerRadius, GLdouble 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 freeglut_teapot.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutWireTeapot( GLdouble size );
|
||||
FGAPI void FGAPIENTRY glutSolidTeapot( GLdouble size );
|
||||
|
||||
/*
|
||||
* Game mode functions, see freeglut_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 freeglut_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 freeglut_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 freeglut_misc.c
|
||||
*/
|
||||
FGAPI void FGAPIENTRY glutIgnoreKeyRepeat( int ignore );
|
||||
FGAPI void FGAPIENTRY glutSetKeyRepeat( int repeatMode );
|
||||
FGAPI void FGAPIENTRY glutForceJoystickFunc( void );
|
||||
|
||||
/*
|
||||
* Misc functions, see freeglut_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__ */
|
||||
|
21
examples/opengl-framework/freeglut/GL/glut.h
Normal file
21
examples/opengl-framework/freeglut/GL/glut.h
Normal 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__ */
|
1
examples/opengl-framework/freeglut/VERSION.txt
Normal file
1
examples/opengl-framework/freeglut/VERSION.txt
Normal file
|
@ -0,0 +1 @@
|
|||
2.8.0
|
412
examples/opengl-framework/freeglut/freeglut_callbacks.c
Normal file
412
examples/opengl-framework/freeglut/freeglut_callbacks.c
Normal file
|
@ -0,0 +1,412 @@
|
|||
/*
|
||||
* freeglut_callbacks.c
|
||||
*
|
||||
* The callbacks setting methods.
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Fri Dec 3 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.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* All of the callbacks setting methods can be generalized to this:
|
||||
*/
|
||||
#define SET_CALLBACK(a) \
|
||||
do \
|
||||
{ \
|
||||
if( fgStructure.CurrentWindow == NULL ) \
|
||||
return; \
|
||||
SET_WCB( ( *( fgStructure.CurrentWindow ) ), a, callback ); \
|
||||
} while( 0 )
|
||||
|
||||
/*
|
||||
* Sets the Display callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutDisplayFunc( void (* callback)( void ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDisplayFunc" );
|
||||
if( !callback )
|
||||
fgError( "Fatal error in program. NULL display callback not "
|
||||
"permitted in GLUT 3.0+ or freeglut 2.0.1+" );
|
||||
SET_CALLBACK( Display );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the Reshape callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutReshapeFunc( void (* callback)( int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReshapeFunc" );
|
||||
SET_CALLBACK( Reshape );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the Keyboard callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutKeyboardFunc( void (* callback)
|
||||
( unsigned char, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutKeyboardFunc" );
|
||||
SET_CALLBACK( Keyboard );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the Special callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutSpecialFunc( void (* callback)( int, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpecialFunc" );
|
||||
SET_CALLBACK( Special );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the global idle callback
|
||||
*/
|
||||
void FGAPIENTRY glutIdleFunc( void (* callback)( void ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIdleFunc" );
|
||||
fgState.IdleCallback = callback;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the Timer callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutTimerFunc( unsigned int timeOut, void (* callback)( int ),
|
||||
int timerID )
|
||||
{
|
||||
SFG_Timer *timer, *node;
|
||||
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTimerFunc" );
|
||||
|
||||
if( (timer = fgState.FreeTimers.Last) )
|
||||
{
|
||||
fgListRemove( &fgState.FreeTimers, &timer->Node );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ! (timer = malloc(sizeof(SFG_Timer))) )
|
||||
fgError( "Fatal error: "
|
||||
"Memory allocation failure in glutTimerFunc()" );
|
||||
}
|
||||
|
||||
timer->Callback = callback;
|
||||
timer->ID = timerID;
|
||||
timer->TriggerTime = fgElapsedTime() + timeOut;
|
||||
|
||||
for( node = fgState.Timers.First; node; node = node->Node.Next )
|
||||
{
|
||||
if( node->TriggerTime > timer->TriggerTime )
|
||||
break;
|
||||
}
|
||||
|
||||
fgListInsert( &fgState.Timers, &node->Node, &timer->Node );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the Visibility callback for the current window.
|
||||
*/
|
||||
static void fghVisibility( int status )
|
||||
{
|
||||
int glut_status = GLUT_VISIBLE;
|
||||
|
||||
FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Visibility Callback" );
|
||||
freeglut_return_if_fail( fgStructure.CurrentWindow );
|
||||
|
||||
if( ( GLUT_HIDDEN == status ) || ( GLUT_FULLY_COVERED == status ) )
|
||||
glut_status = GLUT_NOT_VISIBLE;
|
||||
INVOKE_WCB( *( fgStructure.CurrentWindow ), Visibility, ( glut_status ) );
|
||||
}
|
||||
|
||||
void FGAPIENTRY glutVisibilityFunc( void (* callback)( int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutVisibilityFunc" );
|
||||
SET_CALLBACK( Visibility );
|
||||
|
||||
if( callback )
|
||||
glutWindowStatusFunc( fghVisibility );
|
||||
else
|
||||
glutWindowStatusFunc( NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the keyboard key release callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutKeyboardUpFunc( void (* callback)
|
||||
( unsigned char, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutKeyboardUpFunc" );
|
||||
SET_CALLBACK( KeyboardUp );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the special key release callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutSpecialUpFunc( void (* callback)( int, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpecialUpFunc" );
|
||||
SET_CALLBACK( SpecialUp );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the joystick callback and polling rate for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutJoystickFunc( void (* callback)
|
||||
( unsigned int, int, int, int ),
|
||||
int pollInterval )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutJoystickFunc" );
|
||||
fgInitialiseJoysticks ();
|
||||
|
||||
if ( ( ( fgStructure.CurrentWindow->State.JoystickPollRate < 0 ) ||
|
||||
!FETCH_WCB(*fgStructure.CurrentWindow,Joystick) ) && /* Joystick callback was disabled */
|
||||
( callback && ( pollInterval >= 0 ) ) ) /* but is now enabled */
|
||||
++fgState.NumActiveJoysticks;
|
||||
else if ( ( ( fgStructure.CurrentWindow->State.JoystickPollRate >= 0 ) &&
|
||||
FETCH_WCB(*fgStructure.CurrentWindow,Joystick) ) && /* Joystick callback was enabled */
|
||||
( !callback || ( pollInterval < 0 ) ) ) /* but is now disabled */
|
||||
--fgState.NumActiveJoysticks;
|
||||
|
||||
SET_CALLBACK( Joystick );
|
||||
fgStructure.CurrentWindow->State.JoystickPollRate = pollInterval;
|
||||
|
||||
fgStructure.CurrentWindow->State.JoystickLastPoll =
|
||||
fgElapsedTime() - fgStructure.CurrentWindow->State.JoystickPollRate;
|
||||
|
||||
if( fgStructure.CurrentWindow->State.JoystickLastPoll < 0 )
|
||||
fgStructure.CurrentWindow->State.JoystickLastPoll = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the mouse callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutMouseFunc( void (* callback)( int, int, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMouseFunc" );
|
||||
SET_CALLBACK( Mouse );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the mouse wheel callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutMouseWheelFunc( void (* callback)( int, int, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMouseWheelFunc" );
|
||||
SET_CALLBACK( MouseWheel );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the mouse motion callback for the current window (one or more buttons
|
||||
* are pressed)
|
||||
*/
|
||||
void FGAPIENTRY glutMotionFunc( void (* callback)( int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMotionFunc" );
|
||||
SET_CALLBACK( Motion );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the passive mouse motion callback for the current window (no mouse
|
||||
* buttons are pressed)
|
||||
*/
|
||||
void FGAPIENTRY glutPassiveMotionFunc( void (* callback)( int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPassiveMotionFunc" );
|
||||
SET_CALLBACK( Passive );
|
||||
}
|
||||
|
||||
/*
|
||||
* Window mouse entry/leave callback
|
||||
*/
|
||||
void FGAPIENTRY glutEntryFunc( void (* callback)( int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutEntryFunc" );
|
||||
SET_CALLBACK( Entry );
|
||||
}
|
||||
|
||||
/*
|
||||
* Window destruction callbacks
|
||||
*/
|
||||
void FGAPIENTRY glutCloseFunc( void (* callback)( void ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCloseFunc" );
|
||||
SET_CALLBACK( Destroy );
|
||||
}
|
||||
|
||||
void FGAPIENTRY glutWMCloseFunc( void (* callback)( void ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWMCloseFunc" );
|
||||
glutCloseFunc( callback );
|
||||
}
|
||||
|
||||
/* A. Donev: Destruction callback for menus */
|
||||
void FGAPIENTRY glutMenuDestroyFunc( void (* callback)( void ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuDestroyFunc" );
|
||||
if( fgStructure.CurrentMenu )
|
||||
fgStructure.CurrentMenu->Destroy = callback;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deprecated version of glutMenuStatusFunc callback setting method
|
||||
*/
|
||||
void FGAPIENTRY glutMenuStateFunc( void (* callback)( int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStateFunc" );
|
||||
fgState.MenuStateCallback = callback;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the global menu status callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutMenuStatusFunc( void (* callback)( int, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMenuStatusFunc" );
|
||||
fgState.MenuStatusCallback = callback;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the overlay display callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutOverlayDisplayFunc( void (* callback)( void ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutOverlayDisplayFunc" );
|
||||
SET_CALLBACK( OverlayDisplay );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the window status callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutWindowStatusFunc( void (* callback)( int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWindowStatusFunc" );
|
||||
SET_CALLBACK( WindowStatus );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the spaceball motion callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutSpaceballMotionFunc( void (* callback)( int, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballMotionFunc" );
|
||||
fgInitialiseSpaceball();
|
||||
|
||||
SET_CALLBACK( SpaceMotion );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the spaceball rotate callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutSpaceballRotateFunc( void (* callback)( int, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballRotateFunc" );
|
||||
fgInitialiseSpaceball();
|
||||
|
||||
SET_CALLBACK( SpaceRotation );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the spaceball button callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutSpaceballButtonFunc( void (* callback)( int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSpaceballButtonFunc" );
|
||||
fgInitialiseSpaceball();
|
||||
|
||||
SET_CALLBACK( SpaceButton );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the button box callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutButtonBoxFunc( void (* callback)( int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutButtonBoxFunc" );
|
||||
SET_CALLBACK( ButtonBox );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the dials box callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutDialsFunc( void (* callback)( int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDialsFunc" );
|
||||
SET_CALLBACK( Dials );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the tablet motion callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutTabletMotionFunc( void (* callback)( int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTabletMotionFunc" );
|
||||
SET_CALLBACK( TabletMotion );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the tablet buttons callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutTabletButtonFunc( void (* callback)( int, int, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutTabletButtonFunc" );
|
||||
SET_CALLBACK( TabletButton );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the multi-pointer entry callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutMultiEntryFunc( void (* callback)(int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiEntryFunc" );
|
||||
SET_CALLBACK( MultiEntry );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the multi-pointer button callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutMultiButtonFunc( void (* callback)(int, int, int, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiButtonFunc" );
|
||||
SET_CALLBACK( MultiButton );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the multi-pointer motion callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutMultiMotionFunc( void (* callback)(int, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiMotionFunc" );
|
||||
SET_CALLBACK( MultiMotion );
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the multi-pointer passive motion callback for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutMultiPassiveFunc( void (* callback)(int, int, int ) )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutMultiPassiveFunc" );
|
||||
SET_CALLBACK( MultiPassive );
|
||||
}
|
||||
|
||||
/*** END OF FILE ***/
|
282
examples/opengl-framework/freeglut/freeglut_cursor.c
Normal file
282
examples/opengl-framework/freeglut/freeglut_cursor.c
Normal file
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
* freeglut_cursor.c
|
||||
*
|
||||
* The mouse cursor related stuff.
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Thu Dec 16 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.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
/*
|
||||
* TODO BEFORE THE STABLE RELEASE:
|
||||
* glutSetCursor() -- Win32 mappings are incomplete.
|
||||
*
|
||||
* It would be good to use custom mouse cursor shapes, and introduce
|
||||
* an option to display them using glBitmap() and/or texture mapping,
|
||||
* apart from the windowing system version.
|
||||
*/
|
||||
|
||||
/* -- PRIVATE FUNCTIONS --------------------------------------------------- */
|
||||
|
||||
#if TARGET_HOST_POSIX_X11 || TARGET_HOST_MAC_OSX || TARGET_HOST_SOLARIS
|
||||
#include <X11/cursorfont.h>
|
||||
|
||||
/*
|
||||
* A factory method for an empty cursor
|
||||
*/
|
||||
static Cursor getEmptyCursor( void )
|
||||
{
|
||||
static Cursor cursorNone = None;
|
||||
if( cursorNone == None ) {
|
||||
char cursorNoneBits[ 32 ];
|
||||
XColor dontCare;
|
||||
Pixmap cursorNonePixmap;
|
||||
memset( cursorNoneBits, 0, sizeof( cursorNoneBits ) );
|
||||
memset( &dontCare, 0, sizeof( dontCare ) );
|
||||
cursorNonePixmap = XCreateBitmapFromData ( fgDisplay.Display,
|
||||
fgDisplay.RootWindow,
|
||||
cursorNoneBits, 16, 16 );
|
||||
if( cursorNonePixmap != None ) {
|
||||
cursorNone = XCreatePixmapCursor( fgDisplay.Display,
|
||||
cursorNonePixmap, cursorNonePixmap,
|
||||
&dontCare, &dontCare, 0, 0 );
|
||||
XFreePixmap( fgDisplay.Display, cursorNonePixmap );
|
||||
}
|
||||
}
|
||||
return cursorNone;
|
||||
}
|
||||
|
||||
typedef struct tag_cursorCacheEntry cursorCacheEntry;
|
||||
struct tag_cursorCacheEntry {
|
||||
unsigned int cursorShape; /* an XC_foo value */
|
||||
Cursor cachedCursor; /* None if the corresponding cursor has
|
||||
not been created yet */
|
||||
};
|
||||
|
||||
/*
|
||||
* Note: The arrangement of the table below depends on the fact that
|
||||
* the "normal" GLUT_CURSOR_* values start a 0 and are consecutive.
|
||||
*/
|
||||
static cursorCacheEntry cursorCache[] = {
|
||||
{ XC_arrow, None }, /* GLUT_CURSOR_RIGHT_ARROW */
|
||||
{ XC_top_left_arrow, None }, /* GLUT_CURSOR_LEFT_ARROW */
|
||||
{ XC_hand1, None }, /* GLUT_CURSOR_INFO */
|
||||
{ XC_pirate, None }, /* GLUT_CURSOR_DESTROY */
|
||||
{ XC_question_arrow, None }, /* GLUT_CURSOR_HELP */
|
||||
{ XC_exchange, None }, /* GLUT_CURSOR_CYCLE */
|
||||
{ XC_spraycan, None }, /* GLUT_CURSOR_SPRAY */
|
||||
{ XC_watch, None }, /* GLUT_CURSOR_WAIT */
|
||||
{ XC_xterm, None }, /* GLUT_CURSOR_TEXT */
|
||||
{ XC_crosshair, None }, /* GLUT_CURSOR_CROSSHAIR */
|
||||
{ XC_sb_v_double_arrow, None }, /* GLUT_CURSOR_UP_DOWN */
|
||||
{ XC_sb_h_double_arrow, None }, /* GLUT_CURSOR_LEFT_RIGHT */
|
||||
{ XC_top_side, None }, /* GLUT_CURSOR_TOP_SIDE */
|
||||
{ XC_bottom_side, None }, /* GLUT_CURSOR_BOTTOM_SIDE */
|
||||
{ XC_left_side, None }, /* GLUT_CURSOR_LEFT_SIDE */
|
||||
{ XC_right_side, None }, /* GLUT_CURSOR_RIGHT_SIDE */
|
||||
{ XC_top_left_corner, None }, /* GLUT_CURSOR_TOP_LEFT_CORNER */
|
||||
{ XC_top_right_corner, None }, /* GLUT_CURSOR_TOP_RIGHT_CORNER */
|
||||
{ XC_bottom_right_corner, None }, /* GLUT_CURSOR_BOTTOM_RIGHT_CORNER */
|
||||
{ XC_bottom_left_corner, None } /* GLUT_CURSOR_BOTTOM_LEFT_CORNER */
|
||||
};
|
||||
|
||||
static void fghSetCursor ( SFG_Window *window, int cursorID )
|
||||
{
|
||||
Cursor cursor;
|
||||
/*
|
||||
* XXX FULL_CROSSHAIR demotes to plain CROSSHAIR. Old GLUT allows
|
||||
* for this, but if there is a system that easily supports a full-
|
||||
* window (or full-screen) crosshair, we might consider it.
|
||||
*/
|
||||
int cursorIDToUse =
|
||||
( cursorID == GLUT_CURSOR_FULL_CROSSHAIR ) ? GLUT_CURSOR_CROSSHAIR : cursorID;
|
||||
|
||||
if( ( cursorIDToUse >= 0 ) &&
|
||||
( cursorIDToUse < sizeof( cursorCache ) / sizeof( cursorCache[0] ) ) ) {
|
||||
cursorCacheEntry *entry = &cursorCache[ cursorIDToUse ];
|
||||
if( entry->cachedCursor == None ) {
|
||||
entry->cachedCursor =
|
||||
XCreateFontCursor( fgDisplay.Display, entry->cursorShape );
|
||||
}
|
||||
cursor = entry->cachedCursor;
|
||||
} else {
|
||||
switch( cursorIDToUse )
|
||||
{
|
||||
case GLUT_CURSOR_NONE:
|
||||
cursor = getEmptyCursor( );
|
||||
break;
|
||||
|
||||
case GLUT_CURSOR_INHERIT:
|
||||
cursor = None;
|
||||
break;
|
||||
|
||||
default:
|
||||
fgError( "Unknown cursor type: %d", cursorIDToUse );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( cursorIDToUse == GLUT_CURSOR_INHERIT ) {
|
||||
XUndefineCursor( fgDisplay.Display, window->Window.Handle );
|
||||
} else if ( cursor != None ) {
|
||||
XDefineCursor( fgDisplay.Display, window->Window.Handle, cursor );
|
||||
} else if ( cursorIDToUse != GLUT_CURSOR_NONE ) {
|
||||
fgError( "Failed to create cursor" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void fghWarpPointer ( int x, int y )
|
||||
{
|
||||
XWarpPointer(
|
||||
fgDisplay.Display,
|
||||
None,
|
||||
fgStructure.CurrentWindow->Window.Handle,
|
||||
0, 0, 0, 0,
|
||||
x, y
|
||||
);
|
||||
/* Make the warp visible immediately. */
|
||||
XFlush( fgDisplay.Display );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if TARGET_HOST_MS_WINDOWS
|
||||
static void fghSetCursor ( SFG_Window *window, int cursorID )
|
||||
{
|
||||
/*
|
||||
* Joe Krahn is re-writing the following code.
|
||||
*/
|
||||
/* Set the cursor AND change it for this window class. */
|
||||
#if !defined(__MINGW64__) && _MSC_VER <= 1200
|
||||
# define MAP_CURSOR(a,b) \
|
||||
case a: \
|
||||
SetCursor( LoadCursor( NULL, b ) ); \
|
||||
SetClassLong( window->Window.Handle, \
|
||||
GCL_HCURSOR, \
|
||||
( LONG )LoadCursor( NULL, b ) ); \
|
||||
break;
|
||||
/* Nuke the cursor AND change it for this window class. */
|
||||
# define ZAP_CURSOR(a,b) \
|
||||
case a: \
|
||||
SetCursor( NULL ); \
|
||||
SetClassLong( window->Window.Handle, \
|
||||
GCL_HCURSOR, ( LONG )NULL ); \
|
||||
break;
|
||||
#else
|
||||
# define MAP_CURSOR(a,b) \
|
||||
case a: \
|
||||
SetCursor( LoadCursor( NULL, b ) ); \
|
||||
SetClassLongPtr( window->Window.Handle, \
|
||||
GCLP_HCURSOR, \
|
||||
( LONG )( LONG_PTR )LoadCursor( NULL, b ) ); \
|
||||
break;
|
||||
/* Nuke the cursor AND change it for this window class. */
|
||||
# define ZAP_CURSOR(a,b) \
|
||||
case a: \
|
||||
SetCursor( NULL ); \
|
||||
SetClassLongPtr( window->Window.Handle, \
|
||||
GCLP_HCURSOR, ( LONG )( LONG_PTR )NULL ); \
|
||||
break;
|
||||
#endif
|
||||
|
||||
switch( cursorID )
|
||||
{
|
||||
MAP_CURSOR( GLUT_CURSOR_RIGHT_ARROW, IDC_ARROW );
|
||||
MAP_CURSOR( GLUT_CURSOR_LEFT_ARROW, IDC_ARROW );
|
||||
MAP_CURSOR( GLUT_CURSOR_INFO, IDC_HELP );
|
||||
MAP_CURSOR( GLUT_CURSOR_DESTROY, IDC_CROSS );
|
||||
MAP_CURSOR( GLUT_CURSOR_HELP, IDC_HELP );
|
||||
MAP_CURSOR( GLUT_CURSOR_CYCLE, IDC_SIZEALL );
|
||||
MAP_CURSOR( GLUT_CURSOR_SPRAY, IDC_CROSS );
|
||||
MAP_CURSOR( GLUT_CURSOR_WAIT, IDC_WAIT );
|
||||
MAP_CURSOR( GLUT_CURSOR_TEXT, IDC_IBEAM );
|
||||
MAP_CURSOR( GLUT_CURSOR_CROSSHAIR, IDC_CROSS );
|
||||
MAP_CURSOR( GLUT_CURSOR_UP_DOWN, IDC_SIZENS );
|
||||
MAP_CURSOR( GLUT_CURSOR_LEFT_RIGHT, IDC_SIZEWE );
|
||||
MAP_CURSOR( GLUT_CURSOR_TOP_SIDE, IDC_ARROW ); /* XXX ToDo */
|
||||
MAP_CURSOR( GLUT_CURSOR_BOTTOM_SIDE, IDC_ARROW ); /* XXX ToDo */
|
||||
MAP_CURSOR( GLUT_CURSOR_LEFT_SIDE, IDC_ARROW ); /* XXX ToDo */
|
||||
MAP_CURSOR( GLUT_CURSOR_RIGHT_SIDE, IDC_ARROW ); /* XXX ToDo */
|
||||
MAP_CURSOR( GLUT_CURSOR_TOP_LEFT_CORNER, IDC_SIZENWSE );
|
||||
MAP_CURSOR( GLUT_CURSOR_TOP_RIGHT_CORNER, IDC_SIZENESW );
|
||||
MAP_CURSOR( GLUT_CURSOR_BOTTOM_RIGHT_CORNER, IDC_SIZENWSE );
|
||||
MAP_CURSOR( GLUT_CURSOR_BOTTOM_LEFT_CORNER, IDC_SIZENESW );
|
||||
MAP_CURSOR( GLUT_CURSOR_INHERIT, IDC_ARROW ); /* XXX ToDo */
|
||||
ZAP_CURSOR( GLUT_CURSOR_NONE, NULL );
|
||||
MAP_CURSOR( GLUT_CURSOR_FULL_CROSSHAIR, IDC_CROSS ); /* XXX ToDo */
|
||||
|
||||
default:
|
||||
fgError( "Unknown cursor type: %d", cursorID );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void fghWarpPointer ( int x, int y )
|
||||
{
|
||||
POINT coords;
|
||||
coords.x = x;
|
||||
coords.y = y;
|
||||
|
||||
/* ClientToScreen() translates {coords} for us. */
|
||||
ClientToScreen( fgStructure.CurrentWindow->Window.Handle, &coords );
|
||||
SetCursorPos( coords.x, coords.y );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* -- INTERNAL FUNCTIONS ---------------------------------------------------- */
|
||||
void fgSetCursor ( SFG_Window *window, int cursorID )
|
||||
{
|
||||
fghSetCursor ( window, cursorID );
|
||||
}
|
||||
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Set the cursor image to be used for the current window
|
||||
*/
|
||||
void FGAPIENTRY glutSetCursor( int cursorID )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetCursor" );
|
||||
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSetCursor" );
|
||||
|
||||
fghSetCursor ( fgStructure.CurrentWindow, cursorID );
|
||||
fgStructure.CurrentWindow->State.Cursor = cursorID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Moves the mouse pointer to given window coordinates
|
||||
*/
|
||||
void FGAPIENTRY glutWarpPointer( int x, int y )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWarpPointer" );
|
||||
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutWarpPointer" );
|
||||
|
||||
fghWarpPointer ( x, y );
|
||||
}
|
||||
|
||||
/*** END OF FILE ***/
|
103
examples/opengl-framework/freeglut/freeglut_display.c
Normal file
103
examples/opengl-framework/freeglut/freeglut_display.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* freeglut_display.c
|
||||
*
|
||||
* Display message posting, context buffer swapping.
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Fri Dec 3 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.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Marks the current window to have the redisplay performed when possible...
|
||||
*/
|
||||
void FGAPIENTRY glutPostRedisplay( void )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPostRedisplay" );
|
||||
if ( ! fgStructure.CurrentWindow )
|
||||
{
|
||||
fgError ( " ERROR: Function <%s> called"
|
||||
" with no current window defined.", "glutPostRedisplay" ) ;
|
||||
}
|
||||
|
||||
fgStructure.CurrentWindow->State.Redisplay = GL_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Swaps the buffers for the current window (if any)
|
||||
*/
|
||||
void FGAPIENTRY glutSwapBuffers( void )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSwapBuffers" );
|
||||
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutSwapBuffers" );
|
||||
|
||||
/*
|
||||
* "glXSwapBuffers" already performs an implicit call to "glFlush". What
|
||||
* about "SwapBuffers"?
|
||||
*/
|
||||
glFlush( );
|
||||
if( ! fgStructure.CurrentWindow->Window.DoubleBuffered )
|
||||
return;
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
glXSwapBuffers( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle );
|
||||
#elif TARGET_HOST_MS_WINDOWS
|
||||
SwapBuffers( fgStructure.CurrentWindow->Window.Device );
|
||||
#endif
|
||||
|
||||
/* GLUT_FPS env var support */
|
||||
if( fgState.FPSInterval )
|
||||
{
|
||||
GLint t = glutGet( GLUT_ELAPSED_TIME );
|
||||
fgState.SwapCount++;
|
||||
if( fgState.SwapTime == 0 )
|
||||
fgState.SwapTime = t;
|
||||
else if( t - fgState.SwapTime > fgState.FPSInterval )
|
||||
{
|
||||
float time = 0.001f * ( t - fgState.SwapTime );
|
||||
float fps = ( float )fgState.SwapCount / time;
|
||||
fprintf( stderr,
|
||||
"freeglut: %d frames in %.2f seconds = %.2f FPS\n",
|
||||
fgState.SwapCount, time, fps );
|
||||
fgState.SwapTime = t;
|
||||
fgState.SwapCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark appropriate window to be displayed
|
||||
*/
|
||||
void FGAPIENTRY glutPostWindowRedisplay( int windowID )
|
||||
{
|
||||
SFG_Window* window;
|
||||
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPostWindowRedisplay" );
|
||||
window = fgWindowByID( windowID );
|
||||
freeglut_return_if_fail( window );
|
||||
window->State.Redisplay = GL_TRUE;
|
||||
}
|
||||
|
||||
/*** END OF FILE ***/
|
233
examples/opengl-framework/freeglut/freeglut_ext.c
Normal file
233
examples/opengl-framework/freeglut/freeglut_ext.c
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* freeglut_ext.c
|
||||
*
|
||||
* Functions related to OpenGL extensions.
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Thu Dec 9 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.
|
||||
*/
|
||||
|
||||
#define GLX_GLXEXT_PROTOTYPES
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
static GLUTproc fghGetGLUTProcAddress( 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(glutInit);
|
||||
CHECK_NAME(glutInitDisplayMode);
|
||||
CHECK_NAME(glutInitDisplayString);
|
||||
CHECK_NAME(glutInitWindowPosition);
|
||||
CHECK_NAME(glutInitWindowSize);
|
||||
CHECK_NAME(glutMainLoop);
|
||||
CHECK_NAME(glutExit);
|
||||
CHECK_NAME(glutCreateWindow);
|
||||
CHECK_NAME(glutCreateSubWindow);
|
||||
CHECK_NAME(glutDestroyWindow);
|
||||
CHECK_NAME(glutPostRedisplay);
|
||||
CHECK_NAME(glutPostWindowRedisplay);
|
||||
CHECK_NAME(glutSwapBuffers);
|
||||
CHECK_NAME(glutGetWindow);
|
||||
CHECK_NAME(glutSetWindow);
|
||||
CHECK_NAME(glutSetWindowTitle);
|
||||
CHECK_NAME(glutSetIconTitle);
|
||||
CHECK_NAME(glutPositionWindow);
|
||||
CHECK_NAME(glutReshapeWindow);
|
||||
CHECK_NAME(glutPopWindow);
|
||||
CHECK_NAME(glutPushWindow);
|
||||
CHECK_NAME(glutIconifyWindow);
|
||||
CHECK_NAME(glutShowWindow);
|
||||
CHECK_NAME(glutHideWindow);
|
||||
CHECK_NAME(glutFullScreen);
|
||||
CHECK_NAME(glutSetCursor);
|
||||
CHECK_NAME(glutWarpPointer);
|
||||
CHECK_NAME(glutEstablishOverlay);
|
||||
CHECK_NAME(glutRemoveOverlay);
|
||||
CHECK_NAME(glutUseLayer);
|
||||
CHECK_NAME(glutPostOverlayRedisplay);
|
||||
CHECK_NAME(glutPostWindowOverlayRedisplay);
|
||||
CHECK_NAME(glutShowOverlay);
|
||||
CHECK_NAME(glutHideOverlay);
|
||||
CHECK_NAME(glutCreateMenu);
|
||||
CHECK_NAME(glutDestroyMenu);
|
||||
CHECK_NAME(glutGetMenu);
|
||||
CHECK_NAME(glutSetMenu);
|
||||
CHECK_NAME(glutAddMenuEntry);
|
||||
CHECK_NAME(glutAddSubMenu);
|
||||
CHECK_NAME(glutChangeToMenuEntry);
|
||||
CHECK_NAME(glutChangeToSubMenu);
|
||||
CHECK_NAME(glutRemoveMenuItem);
|
||||
CHECK_NAME(glutAttachMenu);
|
||||
CHECK_NAME(glutDetachMenu);
|
||||
CHECK_NAME(glutDisplayFunc);
|
||||
CHECK_NAME(glutReshapeFunc);
|
||||
CHECK_NAME(glutKeyboardFunc);
|
||||
CHECK_NAME(glutMouseFunc);
|
||||
CHECK_NAME(glutMultiEntryFunc);
|
||||
CHECK_NAME(glutMultiMotionFunc);
|
||||
CHECK_NAME(glutMultiButtonFunc);
|
||||
CHECK_NAME(glutMultiPassiveFunc);
|
||||
CHECK_NAME(glutMotionFunc);
|
||||
CHECK_NAME(glutPassiveMotionFunc);
|
||||
CHECK_NAME(glutEntryFunc);
|
||||
CHECK_NAME(glutVisibilityFunc);
|
||||
CHECK_NAME(glutIdleFunc);
|
||||
CHECK_NAME(glutTimerFunc);
|
||||
CHECK_NAME(glutMenuStateFunc);
|
||||
CHECK_NAME(glutSpecialFunc);
|
||||
CHECK_NAME(glutSpaceballMotionFunc);
|
||||
CHECK_NAME(glutSpaceballRotateFunc);
|
||||
CHECK_NAME(glutSpaceballButtonFunc);
|
||||
CHECK_NAME(glutButtonBoxFunc);
|
||||
CHECK_NAME(glutDialsFunc);
|
||||
CHECK_NAME(glutTabletMotionFunc);
|
||||
CHECK_NAME(glutTabletButtonFunc);
|
||||
CHECK_NAME(glutMenuStatusFunc);
|
||||
CHECK_NAME(glutOverlayDisplayFunc);
|
||||
CHECK_NAME(glutWindowStatusFunc);
|
||||
CHECK_NAME(glutKeyboardUpFunc);
|
||||
CHECK_NAME(glutSpecialUpFunc);
|
||||
#if !defined(_WIN32_WCE)
|
||||
CHECK_NAME(glutJoystickFunc);
|
||||
#endif /* !defined(_WIN32_WCE) */
|
||||
CHECK_NAME(glutSetColor);
|
||||
CHECK_NAME(glutGetColor);
|
||||
CHECK_NAME(glutCopyColormap);
|
||||
CHECK_NAME(glutGet);
|
||||
CHECK_NAME(glutDeviceGet);
|
||||
CHECK_NAME(glutExtensionSupported);
|
||||
CHECK_NAME(glutGetModifiers);
|
||||
CHECK_NAME(glutLayerGet);
|
||||
CHECK_NAME(glutBitmapCharacter);
|
||||
CHECK_NAME(glutBitmapWidth);
|
||||
CHECK_NAME(glutStrokeCharacter);
|
||||
CHECK_NAME(glutStrokeWidth);
|
||||
CHECK_NAME(glutBitmapLength);
|
||||
CHECK_NAME(glutStrokeLength);
|
||||
CHECK_NAME(glutWireSphere);
|
||||
CHECK_NAME(glutSolidSphere);
|
||||
CHECK_NAME(glutWireCone);
|
||||
CHECK_NAME(glutSolidCone);
|
||||
CHECK_NAME(glutWireCube);
|
||||
CHECK_NAME(glutSolidCube);
|
||||
CHECK_NAME(glutWireTorus);
|
||||
CHECK_NAME(glutSolidTorus);
|
||||
CHECK_NAME(glutWireDodecahedron);
|
||||
CHECK_NAME(glutSolidDodecahedron);
|
||||
CHECK_NAME(glutWireTeapot);
|
||||
CHECK_NAME(glutSolidTeapot);
|
||||
CHECK_NAME(glutWireOctahedron);
|
||||
CHECK_NAME(glutSolidOctahedron);
|
||||
CHECK_NAME(glutWireTetrahedron);
|
||||
CHECK_NAME(glutSolidTetrahedron);
|
||||
CHECK_NAME(glutWireIcosahedron);
|
||||
CHECK_NAME(glutSolidIcosahedron);
|
||||
CHECK_NAME(glutVideoResizeGet);
|
||||
CHECK_NAME(glutSetupVideoResizing);
|
||||
CHECK_NAME(glutStopVideoResizing);
|
||||
CHECK_NAME(glutVideoResize);
|
||||
CHECK_NAME(glutVideoPan);
|
||||
CHECK_NAME(glutReportErrors);
|
||||
CHECK_NAME(glutIgnoreKeyRepeat);
|
||||
CHECK_NAME(glutSetKeyRepeat);
|
||||
#if !defined(_WIN32_WCE)
|
||||
CHECK_NAME(glutForceJoystickFunc);
|
||||
CHECK_NAME(glutGameModeString);
|
||||
CHECK_NAME(glutEnterGameMode);
|
||||
CHECK_NAME(glutLeaveGameMode);
|
||||
CHECK_NAME(glutGameModeGet);
|
||||
#endif /* !defined(_WIN32_WCE) */
|
||||
/* freeglut extensions */
|
||||
CHECK_NAME(glutMainLoopEvent);
|
||||
CHECK_NAME(glutLeaveMainLoop);
|
||||
CHECK_NAME(glutCloseFunc);
|
||||
CHECK_NAME(glutWMCloseFunc);
|
||||
CHECK_NAME(glutMenuDestroyFunc);
|
||||
CHECK_NAME(glutFullScreenToggle);
|
||||
CHECK_NAME(glutLeaveFullScreen);
|
||||
CHECK_NAME(glutSetOption);
|
||||
CHECK_NAME(glutGetModeValues);
|
||||
CHECK_NAME(glutSetWindowData);
|
||||
CHECK_NAME(glutGetWindowData);
|
||||
CHECK_NAME(glutSetMenuData);
|
||||
CHECK_NAME(glutGetMenuData);
|
||||
CHECK_NAME(glutBitmapHeight);
|
||||
CHECK_NAME(glutStrokeHeight);
|
||||
CHECK_NAME(glutBitmapString);
|
||||
CHECK_NAME(glutStrokeString);
|
||||
CHECK_NAME(glutWireRhombicDodecahedron);
|
||||
CHECK_NAME(glutSolidRhombicDodecahedron);
|
||||
CHECK_NAME(glutWireSierpinskiSponge);
|
||||
CHECK_NAME(glutSolidSierpinskiSponge);
|
||||
CHECK_NAME(glutWireCylinder);
|
||||
CHECK_NAME(glutSolidCylinder);
|
||||
CHECK_NAME(glutGetProcAddress);
|
||||
CHECK_NAME(glutMouseWheelFunc);
|
||||
CHECK_NAME(glutJoystickGetNumAxes);
|
||||
CHECK_NAME(glutJoystickGetNumButtons);
|
||||
CHECK_NAME(glutJoystickNotWorking);
|
||||
CHECK_NAME(glutJoystickGetDeadBand);
|
||||
CHECK_NAME(glutJoystickSetDeadBand);
|
||||
CHECK_NAME(glutJoystickGetSaturation);
|
||||
CHECK_NAME(glutJoystickSetSaturation);
|
||||
CHECK_NAME(glutJoystickSetMinRange);
|
||||
CHECK_NAME(glutJoystickSetMaxRange);
|
||||
CHECK_NAME(glutJoystickSetCenter);
|
||||
CHECK_NAME(glutJoystickGetMinRange);
|
||||
CHECK_NAME(glutJoystickGetMaxRange);
|
||||
CHECK_NAME(glutJoystickGetCenter);
|
||||
CHECK_NAME(glutInitContextVersion);
|
||||
CHECK_NAME(glutInitContextFlags);
|
||||
CHECK_NAME(glutInitContextProfile);
|
||||
CHECK_NAME(glutInitErrorFunc);
|
||||
CHECK_NAME(glutInitWarningFunc);
|
||||
#undef CHECK_NAME
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
SFG_Proc fghGetProcAddress( const char *procName )
|
||||
{
|
||||
#if TARGET_HOST_MS_WINDOWS
|
||||
return (SFG_Proc)wglGetProcAddress( ( LPCSTR )procName );
|
||||
#elif TARGET_HOST_POSIX_X11 && defined( GLX_ARB_get_proc_address )
|
||||
return (SFG_Proc)glXGetProcAddressARB( ( const GLubyte * )procName );
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
GLUTproc FGAPIENTRY
|
||||
glutGetProcAddress( const char *procName )
|
||||
{
|
||||
GLUTproc p;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetProcAddress" );
|
||||
|
||||
/* Try GLUT functions first, then core GL functions */
|
||||
p = fghGetGLUTProcAddress( procName );
|
||||
return ( p != NULL ) ? p : fghGetProcAddress( procName );
|
||||
}
|
384
examples/opengl-framework/freeglut/freeglut_font.c
Normal file
384
examples/opengl-framework/freeglut/freeglut_font.c
Normal file
|
@ -0,0 +1,384 @@
|
|||
/*
|
||||
* freeglut_font.c
|
||||
*
|
||||
* Bitmap and stroke fonts displaying.
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Thu Dec 16 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.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
/*
|
||||
* TODO BEFORE THE STABLE RELEASE:
|
||||
*
|
||||
* Test things out ...
|
||||
*/
|
||||
|
||||
/* -- IMPORT DECLARATIONS -------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* These are the font faces defined in freeglut_font_data.c file:
|
||||
*/
|
||||
extern SFG_Font fgFontFixed8x13;
|
||||
extern SFG_Font fgFontFixed9x15;
|
||||
extern SFG_Font fgFontHelvetica10;
|
||||
extern SFG_Font fgFontHelvetica12;
|
||||
extern SFG_Font fgFontHelvetica18;
|
||||
extern SFG_Font fgFontTimesRoman10;
|
||||
extern SFG_Font fgFontTimesRoman24;
|
||||
extern SFG_StrokeFont fgStrokeRoman;
|
||||
extern SFG_StrokeFont fgStrokeMonoRoman;
|
||||
|
||||
|
||||
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Matches a font ID with a SFG_Font structure pointer.
|
||||
* This was changed to match the GLUT header style.
|
||||
*/
|
||||
static SFG_Font* fghFontByID( void* font )
|
||||
{
|
||||
if( font == GLUT_BITMAP_8_BY_13 )
|
||||
return &fgFontFixed8x13;
|
||||
if( font == GLUT_BITMAP_9_BY_15 )
|
||||
return &fgFontFixed9x15;
|
||||
if( font == GLUT_BITMAP_HELVETICA_10 )
|
||||
return &fgFontHelvetica10;
|
||||
if( font == GLUT_BITMAP_HELVETICA_12 )
|
||||
return &fgFontHelvetica12;
|
||||
if( font == GLUT_BITMAP_HELVETICA_18 )
|
||||
return &fgFontHelvetica18;
|
||||
if( font == GLUT_BITMAP_TIMES_ROMAN_10 )
|
||||
return &fgFontTimesRoman10;
|
||||
if( font == GLUT_BITMAP_TIMES_ROMAN_24 )
|
||||
return &fgFontTimesRoman24;
|
||||
|
||||
fgWarning( "font 0x%08x not found", font );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Matches a font ID with a SFG_StrokeFont structure pointer.
|
||||
* This was changed to match the GLUT header style.
|
||||
*/
|
||||
static SFG_StrokeFont* fghStrokeByID( void* font )
|
||||
{
|
||||
if( font == GLUT_STROKE_ROMAN )
|
||||
return &fgStrokeRoman;
|
||||
if( font == GLUT_STROKE_MONO_ROMAN )
|
||||
return &fgStrokeMonoRoman;
|
||||
|
||||
fgWarning( "stroke font 0x%08x not found", font );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Draw a bitmap character
|
||||
*/
|
||||
void FGAPIENTRY glutBitmapCharacter( void* fontID, int character )
|
||||
{
|
||||
const GLubyte* face;
|
||||
SFG_Font* font;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapCharacter" );
|
||||
font = fghFontByID( fontID );
|
||||
freeglut_return_if_fail( ( character >= 1 )&&( character < 256 ) );
|
||||
freeglut_return_if_fail( font );
|
||||
|
||||
/*
|
||||
* Find the character we want to draw (???)
|
||||
*/
|
||||
face = font->Characters[ character ];
|
||||
|
||||
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
|
||||
glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE );
|
||||
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE );
|
||||
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
|
||||
glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
|
||||
glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
|
||||
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
|
||||
glBitmap(
|
||||
face[ 0 ], font->Height, /* The bitmap's width and height */
|
||||
font->xorig, font->yorig, /* The origin in the font glyph */
|
||||
( float )( face[ 0 ] ), 0.0, /* The raster advance -- inc. x,y */
|
||||
( face + 1 ) /* The packed bitmap data... */
|
||||
);
|
||||
glPopClientAttrib( );
|
||||
}
|
||||
|
||||
void FGAPIENTRY glutBitmapString( void* fontID, const unsigned char *string )
|
||||
{
|
||||
unsigned char c;
|
||||
float x = 0.0f ;
|
||||
SFG_Font* font;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapString" );
|
||||
font = fghFontByID( fontID );
|
||||
freeglut_return_if_fail( font );
|
||||
if ( !string || ! *string )
|
||||
return;
|
||||
|
||||
glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT );
|
||||
glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE );
|
||||
glPixelStorei( GL_UNPACK_LSB_FIRST, GL_FALSE );
|
||||
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
|
||||
glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 );
|
||||
glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 );
|
||||
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
|
||||
|
||||
/*
|
||||
* Step through the string, drawing each character.
|
||||
* A newline will simply translate the next character's insertion
|
||||
* point back to the start of the line and down one line.
|
||||
*/
|
||||
while( ( c = *string++) )
|
||||
if( c == '\n' )
|
||||
{
|
||||
glBitmap ( 0, 0, 0, 0, -x, (float) -font->Height, NULL );
|
||||
x = 0.0f;
|
||||
}
|
||||
else /* Not an EOL, draw the bitmap character */
|
||||
{
|
||||
const GLubyte* face = font->Characters[ c ];
|
||||
|
||||
glBitmap(
|
||||
face[ 0 ], font->Height, /* Bitmap's width and height */
|
||||
font->xorig, font->yorig, /* The origin in the font glyph */
|
||||
( float )( face[ 0 ] ), 0.0, /* The raster advance; inc. x,y */
|
||||
( face + 1 ) /* The packed bitmap data... */
|
||||
);
|
||||
|
||||
x += ( float )( face[ 0 ] );
|
||||
}
|
||||
|
||||
glPopClientAttrib( );
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the width in pixels of a font's character
|
||||
*/
|
||||
int FGAPIENTRY glutBitmapWidth( void* fontID, int character )
|
||||
{
|
||||
SFG_Font* font;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapWidth" );
|
||||
font = fghFontByID( fontID );
|
||||
freeglut_return_val_if_fail( character > 0 && character < 256, 0 );
|
||||
freeglut_return_val_if_fail( font, 0 );
|
||||
return *( font->Characters[ character ] );
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the width of a string drawn using a bitmap font
|
||||
*/
|
||||
int FGAPIENTRY glutBitmapLength( void* fontID, const unsigned char* string )
|
||||
{
|
||||
unsigned char c;
|
||||
int length = 0, this_line_length = 0;
|
||||
SFG_Font* font;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapLength" );
|
||||
font = fghFontByID( fontID );
|
||||
freeglut_return_val_if_fail( font, 0 );
|
||||
if ( !string || ! *string )
|
||||
return 0;
|
||||
|
||||
while( ( c = *string++) )
|
||||
{
|
||||
if( c != '\n' )/* Not an EOL, increment length of line */
|
||||
this_line_length += *( font->Characters[ c ]);
|
||||
else /* EOL; reset the length of this line */
|
||||
{
|
||||
if( length < this_line_length )
|
||||
length = this_line_length;
|
||||
this_line_length = 0;
|
||||
}
|
||||
}
|
||||
if ( length < this_line_length )
|
||||
length = this_line_length;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the height of a bitmap font
|
||||
*/
|
||||
int FGAPIENTRY glutBitmapHeight( void* fontID )
|
||||
{
|
||||
SFG_Font* font;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutBitmapHeight" );
|
||||
font = fghFontByID( fontID );
|
||||
freeglut_return_val_if_fail( font, 0 );
|
||||
return font->Height;
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw a stroke character
|
||||
*/
|
||||
void FGAPIENTRY glutStrokeCharacter( void* fontID, int character )
|
||||
{
|
||||
const SFG_StrokeChar *schar;
|
||||
const SFG_StrokeStrip *strip;
|
||||
int i, j;
|
||||
SFG_StrokeFont* font;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeCharacter" );
|
||||
font = fghStrokeByID( fontID );
|
||||
freeglut_return_if_fail( character >= 0 );
|
||||
freeglut_return_if_fail( character < font->Quantity );
|
||||
freeglut_return_if_fail( font );
|
||||
|
||||
schar = font->Characters[ character ];
|
||||
freeglut_return_if_fail( schar );
|
||||
strip = schar->Strips;
|
||||
|
||||
for( i = 0; i < schar->Number; i++, strip++ )
|
||||
{
|
||||
glBegin( GL_LINE_STRIP );
|
||||
for( j = 0; j < strip->Number; j++ )
|
||||
glVertex2f( strip->Vertices[ j ].X, strip->Vertices[ j ].Y );
|
||||
glEnd( );
|
||||
glBegin( GL_POINTS );
|
||||
for( j = 0; j < strip->Number; j++ )
|
||||
glVertex2f( strip->Vertices[ j ].X, strip->Vertices[ j ].Y );
|
||||
glEnd( );
|
||||
}
|
||||
glTranslatef( schar->Right, 0.0, 0.0 );
|
||||
}
|
||||
|
||||
void FGAPIENTRY glutStrokeString( void* fontID, const unsigned char *string )
|
||||
{
|
||||
unsigned char c;
|
||||
int i, j;
|
||||
float length = 0.0;
|
||||
SFG_StrokeFont* font;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeString" );
|
||||
font = fghStrokeByID( fontID );
|
||||
freeglut_return_if_fail( font );
|
||||
if ( !string || ! *string )
|
||||
return;
|
||||
|
||||
/*
|
||||
* Step through the string, drawing each character.
|
||||
* A newline will simply translate the next character's insertion
|
||||
* point back to the start of the line and down one line.
|
||||
*/
|
||||
while( ( c = *string++) )
|
||||
if( c < font->Quantity )
|
||||
{
|
||||
if( c == '\n' )
|
||||
{
|
||||
glTranslatef ( -length, -( float )( font->Height ), 0.0 );
|
||||
length = 0.0;
|
||||
}
|
||||
else /* Not an EOL, draw the bitmap character */
|
||||
{
|
||||
const SFG_StrokeChar *schar = font->Characters[ c ];
|
||||
if( schar )
|
||||
{
|
||||
const SFG_StrokeStrip *strip = schar->Strips;
|
||||
|
||||
for( i = 0; i < schar->Number; i++, strip++ )
|
||||
{
|
||||
glBegin( GL_LINE_STRIP );
|
||||
for( j = 0; j < strip->Number; j++ )
|
||||
glVertex2f( strip->Vertices[ j ].X,
|
||||
strip->Vertices[ j ].Y);
|
||||
|
||||
glEnd( );
|
||||
}
|
||||
|
||||
length += schar->Right;
|
||||
glTranslatef( schar->Right, 0.0, 0.0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the width in pixels of a stroke character
|
||||
*/
|
||||
int FGAPIENTRY glutStrokeWidth( void* fontID, int character )
|
||||
{
|
||||
const SFG_StrokeChar *schar;
|
||||
SFG_StrokeFont* font;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeWidth" );
|
||||
font = fghStrokeByID( fontID );
|
||||
freeglut_return_val_if_fail( ( character >= 0 ) &&
|
||||
( character < font->Quantity ),
|
||||
0
|
||||
);
|
||||
freeglut_return_val_if_fail( font, 0 );
|
||||
schar = font->Characters[ character ];
|
||||
freeglut_return_val_if_fail( schar, 0 );
|
||||
|
||||
return ( int )( schar->Right + 0.5 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the width of a string drawn using a stroke font
|
||||
*/
|
||||
int FGAPIENTRY glutStrokeLength( void* fontID, const unsigned char* string )
|
||||
{
|
||||
unsigned char c;
|
||||
float length = 0.0;
|
||||
float this_line_length = 0.0;
|
||||
SFG_StrokeFont* font;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeLength" );
|
||||
font = fghStrokeByID( fontID );
|
||||
freeglut_return_val_if_fail( font, 0 );
|
||||
if ( !string || ! *string )
|
||||
return 0;
|
||||
|
||||
while( ( c = *string++) )
|
||||
if( c < font->Quantity )
|
||||
{
|
||||
if( c == '\n' ) /* EOL; reset the length of this line */
|
||||
{
|
||||
if( length < this_line_length )
|
||||
length = this_line_length;
|
||||
this_line_length = 0.0;
|
||||
}
|
||||
else /* Not an EOL, increment the length of this line */
|
||||
{
|
||||
const SFG_StrokeChar *schar = font->Characters[ c ];
|
||||
if( schar )
|
||||
this_line_length += schar->Right;
|
||||
}
|
||||
}
|
||||
if( length < this_line_length )
|
||||
length = this_line_length;
|
||||
return( int )( length + 0.5 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the height of a stroke font
|
||||
*/
|
||||
GLfloat FGAPIENTRY glutStrokeHeight( void* fontID )
|
||||
{
|
||||
SFG_StrokeFont* font;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutStrokeHeight" );
|
||||
font = fghStrokeByID( fontID );
|
||||
freeglut_return_val_if_fail( font, 0.0 );
|
||||
return font->Height;
|
||||
}
|
||||
|
||||
/*** END OF FILE ***/
|
2020
examples/opengl-framework/freeglut/freeglut_font_data.c
Normal file
2020
examples/opengl-framework/freeglut/freeglut_font_data.c
Normal file
File diff suppressed because it is too large
Load Diff
819
examples/opengl-framework/freeglut/freeglut_gamemode.c
Normal file
819
examples/opengl-framework/freeglut/freeglut_gamemode.c
Normal file
|
@ -0,0 +1,819 @@
|
|||
/*
|
||||
* freeglut_gamemode.c
|
||||
*
|
||||
* The game mode handling code.
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Thu Dec 16 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.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
/*
|
||||
* TODO BEFORE THE STABLE RELEASE:
|
||||
*
|
||||
* glutGameModeString() -- missing
|
||||
* glutEnterGameMode() -- X11 version
|
||||
* glutLeaveGameMode() -- is that correct?
|
||||
* glutGameModeGet() -- is that correct?
|
||||
*/
|
||||
|
||||
|
||||
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
static int xrandr_resize(int xsz, int ysz, int rate, int just_checking)
|
||||
{
|
||||
#ifdef HAVE_X11_EXTENSIONS_XRANDR_H
|
||||
int event_base, error_base, ver_major, ver_minor, use_rate;
|
||||
XRRScreenConfiguration *xrr_config = 0;
|
||||
Status result = -1;
|
||||
|
||||
/* must check at runtime for the availability of the extension */
|
||||
if(!XRRQueryExtension(fgDisplay.Display, &event_base, &error_base)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
XRRQueryVersion(fgDisplay.Display, &ver_major, &ver_minor);
|
||||
|
||||
/* we only heed the rate if we CAN actually use it (Xrandr >= 1.1) and
|
||||
* the user actually cares about it (rate > 0)
|
||||
*/
|
||||
use_rate = ( rate > 0 ) && ( ( ver_major >= 1 ) ||
|
||||
( ( ver_major == 1 ) && ( ver_minor >= 1 ) ) );
|
||||
|
||||
/* this loop is only so that the whole thing will be repeated if someone
|
||||
* else changes video mode between our query of the current information and
|
||||
* the attempt to change it.
|
||||
*/
|
||||
do {
|
||||
XRRScreenSize *ssizes;
|
||||
short *rates;
|
||||
Rotation rot;
|
||||
int i, ssizes_count, rates_count, curr, res_idx = -1;
|
||||
Time timestamp, cfg_timestamp;
|
||||
|
||||
if(xrr_config) {
|
||||
XRRFreeScreenConfigInfo(xrr_config);
|
||||
}
|
||||
|
||||
if(!(xrr_config = XRRGetScreenInfo(fgDisplay.Display, fgDisplay.RootWindow))) {
|
||||
fgWarning("XRRGetScreenInfo failed");
|
||||
break;
|
||||
}
|
||||
ssizes = XRRConfigSizes(xrr_config, &ssizes_count);
|
||||
curr = XRRConfigCurrentConfiguration(xrr_config, &rot);
|
||||
timestamp = XRRConfigTimes(xrr_config, &cfg_timestamp);
|
||||
|
||||
/* if either of xsz or ysz are unspecified, use the current values */
|
||||
if(xsz <= 0)
|
||||
xsz = fgState.GameModeSize.X = ssizes[curr].width;
|
||||
if(ysz <= 0)
|
||||
ysz = fgState.GameModeSize.Y = ssizes[curr].height;
|
||||
|
||||
|
||||
if(xsz == ssizes[curr].width && ysz == ssizes[curr].height) {
|
||||
/* no need to switch, we're already in the requested resolution */
|
||||
res_idx = curr;
|
||||
} else {
|
||||
for(i=0; i<ssizes_count; i++) {
|
||||
if(ssizes[i].width == xsz && ssizes[i].height == ysz) {
|
||||
res_idx = i;
|
||||
break; /* found it */
|
||||
}
|
||||
}
|
||||
}
|
||||
if(res_idx == -1)
|
||||
break; /* no matching resolution */
|
||||
|
||||
#if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
|
||||
if(use_rate) {
|
||||
rate = fgState.GameModeRefresh;
|
||||
|
||||
/* for the selected resolution, let's find out if there is
|
||||
* a matching refresh rate available.
|
||||
*/
|
||||
rates = XRRConfigRates(xrr_config, res_idx, &rates_count);
|
||||
|
||||
for(i=0; i<rates_count; i++) {
|
||||
if(rates[i] == rate) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == rates_count) {
|
||||
break; /* no matching rate */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(just_checking) {
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
#if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
|
||||
if(use_rate)
|
||||
result = XRRSetScreenConfigAndRate(fgDisplay.Display, xrr_config,
|
||||
fgDisplay.RootWindow, res_idx, rot, rate, timestamp);
|
||||
else
|
||||
#endif
|
||||
result = XRRSetScreenConfig(fgDisplay.Display, xrr_config,
|
||||
fgDisplay.RootWindow, res_idx, rot, timestamp);
|
||||
|
||||
} while(result == RRSetConfigInvalidTime);
|
||||
|
||||
if(xrr_config) {
|
||||
XRRFreeScreenConfigInfo(xrr_config);
|
||||
}
|
||||
|
||||
if(result == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_X11_EXTENSIONS_XRANDR_H */
|
||||
return -1;
|
||||
}
|
||||
#endif /* TARGET_HOST_POSIX_X11 */
|
||||
|
||||
/*
|
||||
* Remembers the current visual settings, so that
|
||||
* we can change them and restore later...
|
||||
*/
|
||||
static void fghRememberState( void )
|
||||
{
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
int event_base, error_base;
|
||||
|
||||
/*
|
||||
* Remember the current pointer location before going fullscreen
|
||||
* for restoring it later:
|
||||
*/
|
||||
Window junk_window;
|
||||
unsigned int junk_mask;
|
||||
|
||||
XQueryPointer(fgDisplay.Display, fgDisplay.RootWindow,
|
||||
&junk_window, &junk_window,
|
||||
&fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY,
|
||||
&fgDisplay.DisplayPointerX, &fgDisplay.DisplayPointerY, &junk_mask);
|
||||
|
||||
# ifdef HAVE_X11_EXTENSIONS_XRANDR_H
|
||||
if(XRRQueryExtension(fgDisplay.Display, &event_base, &error_base)) {
|
||||
XRRScreenConfiguration *xrr_config;
|
||||
XRRScreenSize *ssizes;
|
||||
Rotation rot;
|
||||
int ssize_count, curr;
|
||||
|
||||
if((xrr_config = XRRGetScreenInfo(fgDisplay.Display, fgDisplay.RootWindow))) {
|
||||
ssizes = XRRConfigSizes(xrr_config, &ssize_count);
|
||||
curr = XRRConfigCurrentConfiguration(xrr_config, &rot);
|
||||
|
||||
fgDisplay.prev_xsz = ssizes[curr].width;
|
||||
fgDisplay.prev_ysz = ssizes[curr].height;
|
||||
fgDisplay.prev_refresh = -1;
|
||||
|
||||
# if ( RANDR_MAJOR >= 1 ) || ( ( RANDR_MAJOR == 1 ) && ( RANDR_MINOR >= 1 ) )
|
||||
if(fgState.GameModeRefresh != -1) {
|
||||
fgDisplay.prev_refresh = XRRConfigCurrentRate(xrr_config);
|
||||
}
|
||||
# endif
|
||||
|
||||
fgDisplay.prev_size_valid = 1;
|
||||
|
||||
XRRFreeScreenConfigInfo(xrr_config);
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
* This highly depends on the XFree86 extensions,
|
||||
* not approved as X Consortium standards
|
||||
*/
|
||||
# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
|
||||
if(!XF86VidModeQueryExtension(fgDisplay.Display, &event_base, &error_base)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remember the current ViewPort location of the screen to be able to
|
||||
* restore the ViewPort on LeaveGameMode():
|
||||
*/
|
||||
if( !XF86VidModeGetViewPort(
|
||||
fgDisplay.Display,
|
||||
fgDisplay.Screen,
|
||||
&fgDisplay.DisplayViewPortX,
|
||||
&fgDisplay.DisplayViewPortY ) )
|
||||
fgWarning( "XF86VidModeGetViewPort failed" );
|
||||
|
||||
|
||||
/* Query the current display settings: */
|
||||
fgDisplay.DisplayModeValid =
|
||||
XF86VidModeGetModeLine(
|
||||
fgDisplay.Display,
|
||||
fgDisplay.Screen,
|
||||
&fgDisplay.DisplayModeClock,
|
||||
&fgDisplay.DisplayMode
|
||||
);
|
||||
|
||||
if( !fgDisplay.DisplayModeValid )
|
||||
fgWarning( "XF86VidModeGetModeLine failed" );
|
||||
# endif
|
||||
|
||||
#elif TARGET_HOST_MS_WINDOWS
|
||||
|
||||
/* DEVMODE devMode; */
|
||||
|
||||
/* Grab the current desktop settings... */
|
||||
|
||||
/* hack to get around my stupid cross-gcc headers */
|
||||
#define FREEGLUT_ENUM_CURRENT_SETTINGS -1
|
||||
|
||||
EnumDisplaySettings( fgDisplay.DisplayName, FREEGLUT_ENUM_CURRENT_SETTINGS,
|
||||
&fgDisplay.DisplayMode );
|
||||
|
||||
/* Make sure we will be restoring all settings needed */
|
||||
fgDisplay.DisplayMode.dmFields |=
|
||||
DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Restores the previously remembered visual settings
|
||||
*/
|
||||
static void fghRestoreState( void )
|
||||
{
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
/* Restore the remembered pointer position: */
|
||||
XWarpPointer(
|
||||
fgDisplay.Display, None, fgDisplay.RootWindow, 0, 0, 0, 0,
|
||||
fgDisplay.DisplayPointerX, fgDisplay.DisplayPointerY
|
||||
);
|
||||
|
||||
|
||||
# ifdef HAVE_X11_EXTENSIONS_XRANDR_H
|
||||
if(fgDisplay.prev_size_valid) {
|
||||
if(xrandr_resize(fgDisplay.prev_xsz, fgDisplay.prev_ysz, fgDisplay.prev_refresh, 0) != -1) {
|
||||
fgDisplay.prev_size_valid = 0;
|
||||
# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
|
||||
fgDisplay.DisplayModeValid = 0;
|
||||
# endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
|
||||
# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
|
||||
/*
|
||||
* This highly depends on the XFree86 extensions,
|
||||
* not approved as X Consortium standards
|
||||
*/
|
||||
|
||||
if( fgDisplay.DisplayModeValid )
|
||||
{
|
||||
XF86VidModeModeInfo** displayModes;
|
||||
int i, displayModesCount;
|
||||
|
||||
if( !XF86VidModeGetAllModeLines(
|
||||
fgDisplay.Display,
|
||||
fgDisplay.Screen,
|
||||
&displayModesCount,
|
||||
&displayModes ) )
|
||||
{
|
||||
fgWarning( "XF86VidModeGetAllModeLines failed" );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check every of the modes looking for one that matches our demands.
|
||||
* If we find one, switch to it and restore the remembered viewport.
|
||||
*/
|
||||
for( i = 0; i < displayModesCount; i++ )
|
||||
{
|
||||
if(displayModes[ i ]->hdisplay == fgDisplay.DisplayMode.hdisplay &&
|
||||
displayModes[ i ]->vdisplay == fgDisplay.DisplayMode.vdisplay &&
|
||||
displayModes[ i ]->dotclock == fgDisplay.DisplayModeClock )
|
||||
{
|
||||
if( !XF86VidModeSwitchToMode(
|
||||
fgDisplay.Display,
|
||||
fgDisplay.Screen,
|
||||
displayModes[ i ] ) )
|
||||
{
|
||||
fgWarning( "XF86VidModeSwitchToMode failed" );
|
||||
break;
|
||||
}
|
||||
|
||||
if( !XF86VidModeSetViewPort(
|
||||
fgDisplay.Display,
|
||||
fgDisplay.Screen,
|
||||
fgDisplay.DisplayViewPortX,
|
||||
fgDisplay.DisplayViewPortY ) )
|
||||
fgWarning( "XF86VidModeSetViewPort failed" );
|
||||
|
||||
|
||||
/*
|
||||
* For the case this would be the last X11 call the application
|
||||
* calls exit() we've to flush the X11 output queue to have the
|
||||
* commands sent to the X server before the application exits.
|
||||
*/
|
||||
XFlush( fgDisplay.Display );
|
||||
|
||||
fgDisplay.DisplayModeValid = 0;
|
||||
# ifdef HAVE_X11_EXTENSIONS_XRANDR_H
|
||||
fgDisplay.prev_size_valid = 0;
|
||||
# endif
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
XFree( displayModes );
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#elif TARGET_HOST_MS_WINDOWS
|
||||
|
||||
/* Restore the previously remembered desktop display settings */
|
||||
ChangeDisplaySettingsEx( fgDisplay.DisplayName,&fgDisplay.DisplayMode, 0,0,0 );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
|
||||
|
||||
/*
|
||||
* Checks a single display mode settings against user's preferences.
|
||||
*/
|
||||
static GLboolean fghCheckDisplayMode( int width, int height, int depth, int refresh )
|
||||
{
|
||||
/* The desired values should be stored in fgState structure... */
|
||||
return ( width == fgState.GameModeSize.X ) &&
|
||||
( height == fgState.GameModeSize.Y ) &&
|
||||
( depth == fgState.GameModeDepth ) &&
|
||||
( refresh == fgState.GameModeRefresh );
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks all display modes settings against user's preferences.
|
||||
* Returns the mode number found or -1 if none could be found.
|
||||
*/
|
||||
static int fghCheckDisplayModes( GLboolean exactMatch, int displayModesCount, XF86VidModeModeInfo** displayModes )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < displayModesCount; i++ )
|
||||
{
|
||||
/* Compute the displays refresh rate, dotclock comes in kHz. */
|
||||
int refresh = ( displayModes[ i ]->dotclock * 1000 ) /
|
||||
( displayModes[ i ]->htotal * displayModes[ i ]->vtotal );
|
||||
|
||||
if( fghCheckDisplayMode( displayModes[ i ]->hdisplay,
|
||||
displayModes[ i ]->vdisplay,
|
||||
fgState.GameModeDepth,
|
||||
( exactMatch ? refresh : fgState.GameModeRefresh ) ) ) {
|
||||
if (!exactMatch)
|
||||
{
|
||||
/* Update the chosen refresh rate, otherwise a
|
||||
* glutGameModeGet(GLUT_GAME_MODE_REFRESH_RATE) would not
|
||||
* return the right values
|
||||
*/
|
||||
fgState.GameModeRefresh = refresh;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Changes the current display mode to match user's settings
|
||||
*/
|
||||
static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
|
||||
{
|
||||
GLboolean success = GL_FALSE;
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
|
||||
/* first try to use XRandR, then fallback to XF86VidMode */
|
||||
# ifdef HAVE_X11_EXTENSIONS_XRANDR_H
|
||||
if(xrandr_resize(fgState.GameModeSize.X, fgState.GameModeSize.Y,
|
||||
fgState.GameModeRefresh, haveToTest) != -1) {
|
||||
return GL_TRUE;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
/*
|
||||
* This highly depends on the XFree86 extensions,
|
||||
* not approved as X Consortium standards
|
||||
*/
|
||||
# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
|
||||
|
||||
/*
|
||||
* This is also used by applications which check modes by calling
|
||||
* glutGameModeGet(GLUT_GAME_MODE_POSSIBLE), so allow the check:
|
||||
*/
|
||||
if( haveToTest || fgDisplay.DisplayModeValid )
|
||||
{
|
||||
XF86VidModeModeInfo** displayModes;
|
||||
int i, displayModesCount;
|
||||
|
||||
/* If we don't have a valid modeline in the display structure, which
|
||||
* can happen if this is called from glutGameModeGet instead of
|
||||
* glutEnterGameMode, then we need to query the current mode, to make
|
||||
* unspecified settings to default to their current values.
|
||||
*/
|
||||
if(!fgDisplay.DisplayModeValid) {
|
||||
if(!XF86VidModeGetModeLine(fgDisplay.Display, fgDisplay.Screen,
|
||||
&fgDisplay.DisplayModeClock, &fgDisplay.DisplayMode)) {
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
if (fgState.GameModeSize.X == -1)
|
||||
{
|
||||
fgState.GameModeSize.X = fgDisplay.DisplayMode.hdisplay;
|
||||
}
|
||||
if (fgState.GameModeSize.Y == -1)
|
||||
{
|
||||
fgState.GameModeSize.Y = fgDisplay.DisplayMode.vdisplay;
|
||||
}
|
||||
if (fgState.GameModeDepth == -1)
|
||||
{
|
||||
/* can't get color depth from this, nor can we change it, do nothing
|
||||
* TODO: get with XGetVisualInfo()? but then how to set?
|
||||
*/
|
||||
}
|
||||
if (fgState.GameModeRefresh == -1)
|
||||
{
|
||||
/* Compute the displays refresh rate, dotclock comes in kHz. */
|
||||
int refresh = ( fgDisplay.DisplayModeClock * 1000 ) /
|
||||
( fgDisplay.DisplayMode.htotal * fgDisplay.DisplayMode.vtotal );
|
||||
|
||||
fgState.GameModeRefresh = refresh;
|
||||
}
|
||||
|
||||
/* query all possible display modes */
|
||||
if( !XF86VidModeGetAllModeLines(
|
||||
fgDisplay.Display,
|
||||
fgDisplay.Screen,
|
||||
&displayModesCount,
|
||||
&displayModes ) )
|
||||
{
|
||||
fgWarning( "XF86VidModeGetAllModeLines failed" );
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check every of the modes looking for one that matches our demands,
|
||||
* ignoring the refresh rate if no exact match could be found.
|
||||
*/
|
||||
i = fghCheckDisplayModes( GL_TRUE, displayModesCount, displayModes );
|
||||
if( i < 0 ) {
|
||||
i = fghCheckDisplayModes( GL_FALSE, displayModesCount, displayModes );
|
||||
}
|
||||
success = ( i < 0 ) ? GL_FALSE : GL_TRUE;
|
||||
|
||||
if( !haveToTest && success ) {
|
||||
if( !XF86VidModeSwitchToMode(
|
||||
fgDisplay.Display,
|
||||
fgDisplay.Screen,
|
||||
displayModes[ i ] ) )
|
||||
fgWarning( "XF86VidModeSwitchToMode failed" );
|
||||
}
|
||||
|
||||
XFree( displayModes );
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
#elif TARGET_HOST_MS_WINDOWS
|
||||
|
||||
DEVMODE devMode;
|
||||
char *fggmstr = NULL;
|
||||
char displayMode[300];
|
||||
|
||||
success = GL_FALSE;
|
||||
|
||||
EnumDisplaySettings( fgDisplay.DisplayName, -1, &devMode );
|
||||
devMode.dmFields = 0;
|
||||
|
||||
if (fgState.GameModeSize.X!=-1)
|
||||
{
|
||||
devMode.dmPelsWidth = fgState.GameModeSize.X;
|
||||
devMode.dmFields |= DM_PELSWIDTH;
|
||||
}
|
||||
if (fgState.GameModeSize.Y!=-1)
|
||||
{
|
||||
devMode.dmPelsHeight = fgState.GameModeSize.Y;
|
||||
devMode.dmFields |= DM_PELSHEIGHT;
|
||||
}
|
||||
if (fgState.GameModeDepth!=-1)
|
||||
{
|
||||
devMode.dmBitsPerPel = fgState.GameModeDepth;
|
||||
devMode.dmFields |= DM_BITSPERPEL;
|
||||
}
|
||||
if (fgState.GameModeRefresh!=-1)
|
||||
{
|
||||
devMode.dmDisplayFrequency = fgState.GameModeRefresh;
|
||||
devMode.dmFields |= DM_DISPLAYFREQUENCY;
|
||||
}
|
||||
|
||||
switch ( ChangeDisplaySettingsEx(fgDisplay.DisplayName, &devMode, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) )
|
||||
{
|
||||
case DISP_CHANGE_SUCCESSFUL:
|
||||
success = GL_TRUE;
|
||||
|
||||
if (!haveToTest)
|
||||
{
|
||||
/* update vars in case if windows switched to proper mode */
|
||||
EnumDisplaySettings( fgDisplay.DisplayName, FREEGLUT_ENUM_CURRENT_SETTINGS, &devMode );
|
||||
fgState.GameModeSize.X = devMode.dmPelsWidth;
|
||||
fgState.GameModeSize.Y = devMode.dmPelsHeight;
|
||||
fgState.GameModeDepth = devMode.dmBitsPerPel;
|
||||
fgState.GameModeRefresh = devMode.dmDisplayFrequency;
|
||||
}
|
||||
break;
|
||||
case DISP_CHANGE_RESTART:
|
||||
fggmstr = "The computer must be restarted for the graphics mode to work.";
|
||||
break;
|
||||
case DISP_CHANGE_BADFLAGS:
|
||||
fggmstr = "An invalid set of flags was passed in.";
|
||||
break;
|
||||
case DISP_CHANGE_BADPARAM:
|
||||
fggmstr = "An invalid parameter was passed in. This can include an invalid flag or combination of flags.";
|
||||
break;
|
||||
case DISP_CHANGE_FAILED:
|
||||
fggmstr = "The display driver failed the specified graphics mode.";
|
||||
break;
|
||||
case DISP_CHANGE_BADMODE:
|
||||
fggmstr = "The graphics mode is not supported.";
|
||||
break;
|
||||
default:
|
||||
fggmstr = "Unknown error in graphics mode???"; /* dunno if it is possible,MSDN does not mention any other error */
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !success )
|
||||
{
|
||||
/* I'd rather get info whats going on in my program than wonder about */
|
||||
/* magic happenings behind my back, its lib for devels at last ;) */
|
||||
|
||||
/* append display mode to error to make things more informative */
|
||||
sprintf(displayMode,"%s Problem with requested mode: %ix%i:%i@%i", fggmstr, devMode.dmPelsWidth, devMode.dmPelsHeight, devMode.dmBitsPerPel, devMode.dmDisplayFrequency);
|
||||
fgWarning(displayMode);
|
||||
}
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Sets the game mode display string
|
||||
*/
|
||||
void FGAPIENTRY glutGameModeString( const char* string )
|
||||
{
|
||||
int width = -1, height = -1, depth = -1, refresh = -1;
|
||||
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGameModeString" );
|
||||
|
||||
/*
|
||||
* This one seems a bit easier than glutInitDisplayString. The bad thing
|
||||
* about it that I was unable to find the game mode string definition, so
|
||||
* that I assumed it is: "[width]x[height]:[depth]@[refresh rate]", which
|
||||
* appears in all GLUT game mode programs I have seen to date.
|
||||
*/
|
||||
if( sscanf( string, "%ix%i:%i@%i", &width, &height, &depth, &refresh ) !=
|
||||
4 )
|
||||
if( sscanf( string, "%ix%i:%i", &width, &height, &depth ) != 3 )
|
||||
if( sscanf( string, "%ix%i@%i", &width, &height, &refresh ) != 3 )
|
||||
if( sscanf( string, "%ix%i", &width, &height ) != 2 )
|
||||
if( sscanf( string, ":%i@%i", &depth, &refresh ) != 2 )
|
||||
if( sscanf( string, ":%i", &depth ) != 1 )
|
||||
if( sscanf( string, "@%i", &refresh ) != 1 )
|
||||
fgWarning(
|
||||
"unable to parse game mode string `%s'",
|
||||
string
|
||||
);
|
||||
|
||||
/* All values not specified are now set to -1, which means those
|
||||
* aspects of the current display mode are not changed in
|
||||
* fghChangeDisplayMode() above.
|
||||
*/
|
||||
fgState.GameModeSize.X = width;
|
||||
fgState.GameModeSize.Y = height;
|
||||
fgState.GameModeDepth = depth;
|
||||
fgState.GameModeRefresh = refresh;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Enters the game mode
|
||||
*/
|
||||
int FGAPIENTRY glutEnterGameMode( void )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutEnterGameMode" );
|
||||
|
||||
if( fgStructure.GameModeWindow )
|
||||
fgAddToWindowDestroyList( fgStructure.GameModeWindow );
|
||||
else
|
||||
fghRememberState( );
|
||||
|
||||
if( ! fghChangeDisplayMode( GL_FALSE ) )
|
||||
{
|
||||
fgWarning( "failed to change screen settings" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
fgStructure.GameModeWindow = fgCreateWindow(
|
||||
NULL, "FREEGLUT", GL_TRUE, 0, 0,
|
||||
GL_TRUE, fgState.GameModeSize.X, fgState.GameModeSize.Y,
|
||||
GL_TRUE, GL_FALSE
|
||||
);
|
||||
|
||||
fgStructure.GameModeWindow->State.Width = fgState.GameModeSize.X;
|
||||
fgStructure.GameModeWindow->State.Height = fgState.GameModeSize.Y;
|
||||
fgStructure.GameModeWindow->State.NeedToResize = GL_TRUE;
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
|
||||
/*
|
||||
* Sync needed to avoid a real race, the Xserver must have really created
|
||||
* the window before we can grab the pointer into it:
|
||||
*/
|
||||
XSync( fgDisplay.Display, False );
|
||||
/*
|
||||
* Grab the pointer to confine it into the window after the calls to
|
||||
* XWrapPointer() which ensure that the pointer really enters the window.
|
||||
*
|
||||
* We also need to wait here until XGrabPointer() returns GrabSuccess,
|
||||
* otherwise the new window is not viewable yet and if the next function
|
||||
* (XSetInputFocus) is called with a not yet viewable window, it will exit
|
||||
* the application which we have to aviod, so wait until it's viewable:
|
||||
*/
|
||||
while( GrabSuccess != XGrabPointer(
|
||||
fgDisplay.Display, fgStructure.GameModeWindow->Window.Handle,
|
||||
TRUE,
|
||||
ButtonPressMask | ButtonReleaseMask | ButtonMotionMask
|
||||
| PointerMotionMask,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
fgStructure.GameModeWindow->Window.Handle, None, CurrentTime) )
|
||||
usleep( 100 );
|
||||
/*
|
||||
* Change input focus to the new window. This will exit the application
|
||||
* if the new window is not viewable yet, see the XGrabPointer loop above.
|
||||
*/
|
||||
XSetInputFocus(
|
||||
fgDisplay.Display,
|
||||
fgStructure.GameModeWindow->Window.Handle,
|
||||
RevertToNone,
|
||||
CurrentTime
|
||||
);
|
||||
|
||||
/* Move the Pointer to the middle of the fullscreen window */
|
||||
XWarpPointer(
|
||||
fgDisplay.Display,
|
||||
None,
|
||||
fgDisplay.RootWindow,
|
||||
0, 0, 0, 0,
|
||||
fgState.GameModeSize.X/2, fgState.GameModeSize.Y/2
|
||||
);
|
||||
|
||||
# ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
|
||||
|
||||
if( fgDisplay.DisplayModeValid )
|
||||
{
|
||||
int x, y;
|
||||
Window child;
|
||||
|
||||
/* Change to viewport to the window topleft edge: */
|
||||
if( !XF86VidModeSetViewPort( fgDisplay.Display, fgDisplay.Screen, 0, 0 ) )
|
||||
fgWarning( "XF86VidModeSetViewPort failed" );
|
||||
|
||||
/*
|
||||
* Final window repositioning: It could be avoided using an undecorated
|
||||
* window using override_redirect, but this * would possily require
|
||||
* more changes and investigation.
|
||||
*/
|
||||
|
||||
/* Get the current postion of the drawable area on screen */
|
||||
XTranslateCoordinates(
|
||||
fgDisplay.Display,
|
||||
fgStructure.CurrentWindow->Window.Handle,
|
||||
fgDisplay.RootWindow,
|
||||
0, 0, &x, &y,
|
||||
&child
|
||||
);
|
||||
|
||||
/* Move the decorataions out of the topleft corner of the display */
|
||||
XMoveWindow( fgDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
|
||||
-x, -y);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Grab the keyboard, too */
|
||||
XGrabKeyboard(
|
||||
fgDisplay.Display,
|
||||
fgStructure.GameModeWindow->Window.Handle,
|
||||
FALSE,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
CurrentTime
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
return fgStructure.GameModeWindow->ID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Leaves the game mode
|
||||
*/
|
||||
void FGAPIENTRY glutLeaveGameMode( void )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutLeaveGameMode" );
|
||||
|
||||
freeglut_return_if_fail( fgStructure.GameModeWindow );
|
||||
|
||||
fgAddToWindowDestroyList( fgStructure.GameModeWindow );
|
||||
fgStructure.GameModeWindow = NULL;
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
|
||||
XUngrabPointer( fgDisplay.Display, CurrentTime );
|
||||
XUngrabKeyboard( fgDisplay.Display, CurrentTime );
|
||||
|
||||
#endif
|
||||
|
||||
fghRestoreState();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns information concerning the freeglut game mode
|
||||
*/
|
||||
int FGAPIENTRY glutGameModeGet( GLenum eWhat )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGameModeGet" );
|
||||
|
||||
switch( eWhat )
|
||||
{
|
||||
case GLUT_GAME_MODE_ACTIVE:
|
||||
return !!fgStructure.GameModeWindow;
|
||||
|
||||
case GLUT_GAME_MODE_POSSIBLE:
|
||||
return fghChangeDisplayMode( GL_TRUE );
|
||||
|
||||
case GLUT_GAME_MODE_WIDTH:
|
||||
return fgState.GameModeSize.X;
|
||||
|
||||
case GLUT_GAME_MODE_HEIGHT:
|
||||
return fgState.GameModeSize.Y;
|
||||
|
||||
case GLUT_GAME_MODE_PIXEL_DEPTH:
|
||||
return fgState.GameModeDepth;
|
||||
|
||||
case GLUT_GAME_MODE_REFRESH_RATE:
|
||||
return fgState.GameModeRefresh;
|
||||
|
||||
case GLUT_GAME_MODE_DISPLAY_CHANGED:
|
||||
/*
|
||||
* This is true if the game mode has been activated successfully..
|
||||
*/
|
||||
return !!fgStructure.GameModeWindow;
|
||||
}
|
||||
|
||||
fgWarning( "Unknown gamemode get: %d", eWhat );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*** END OF FILE ***/
|
1215
examples/opengl-framework/freeglut/freeglut_geometry.c
Normal file
1215
examples/opengl-framework/freeglut/freeglut_geometry.c
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* freeglut_glutfont_definitions.c
|
||||
*
|
||||
* Bitmap and stroke fonts displaying.
|
||||
*
|
||||
* Copyright (c) 2003 Stephen J. Baker (whether he wants it or not).
|
||||
* All Rights Reserved.
|
||||
* Written by John F. Fay <fayjf@sourceforge.net>, who releases the
|
||||
* copyright over to the "freeglut" project lead.
|
||||
* Creation date: Mon July 21 2003
|
||||
*
|
||||
* 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 file is necessary for the *nix version of "freeglut" because the
|
||||
* original GLUT defined its font variables in rather an unusual way.
|
||||
* Publicly, in "glut.h", they were defined as "void *". Privately,
|
||||
* in one of the source code files, they were defined as pointers to a
|
||||
* structure. Most compilers and linkers are satisfied with the "void *"
|
||||
* and don't go any farther, but some of them balked. In particular,
|
||||
* when compiling with "freeglut" and then trying to run using the GLUT
|
||||
* ".so" library, some of them would give an error. So we are having to
|
||||
* create this file to define the variables as pointers to an unusual
|
||||
* structure to match GLUT.
|
||||
*/
|
||||
|
||||
/*
|
||||
* freeglut_internal.h uses some GL types, but including the GL header portably
|
||||
* is a bit tricky, so we include freeglut_std.h here, which contains the
|
||||
* necessary machinery. But this poses another problem, caused by the ugly
|
||||
* original defintion of the font constants in "classic" GLUT: They are defined
|
||||
* as void* externally, so we move them temporarily out of the way by AN EXTREME
|
||||
* CPP HACK.
|
||||
*/
|
||||
|
||||
#define glutStrokeRoman glutStrokeRomanIGNOREME
|
||||
#define glutStrokeMonoRoman glutStrokeMonoRomanIGNOREME
|
||||
#define glutBitmap9By15 glutBitmap9By15IGNOREME
|
||||
#define glutBitmap8By13 glutBitmap8By13IGNOREME
|
||||
#define glutBitmapTimesRoman10 glutBitmapTimesRoman10IGNOREME
|
||||
#define glutBitmapTimesRoman24 glutBitmapTimesRoman24IGNOREME
|
||||
#define glutBitmapHelvetica10 glutBitmapHelvetica10IGNOREME
|
||||
#define glutBitmapHelvetica12 glutBitmapHelvetica12IGNOREME
|
||||
#define glutBitmapHelvetica18 glutBitmapHelvetica18IGNOREME
|
||||
|
||||
#include <GL/freeglut_std.h>
|
||||
|
||||
#undef glutStrokeRoman
|
||||
#undef glutStrokeMonoRoman
|
||||
#undef glutBitmap9By15
|
||||
#undef glutBitmap8By13
|
||||
#undef glutBitmapTimesRoman10
|
||||
#undef glutBitmapTimesRoman24
|
||||
#undef glutBitmapHelvetica10
|
||||
#undef glutBitmapHelvetica12
|
||||
#undef glutBitmapHelvetica18
|
||||
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
|
||||
struct freeglutStrokeFont
|
||||
{
|
||||
const char *name ;
|
||||
int num_chars ;
|
||||
void *ch ;
|
||||
float top ;
|
||||
float bottom ;
|
||||
};
|
||||
|
||||
struct freeglutBitmapFont
|
||||
{
|
||||
const char *name ;
|
||||
const int num_chars ;
|
||||
const int first ;
|
||||
const void *ch ;
|
||||
};
|
||||
|
||||
|
||||
struct freeglutStrokeFont glutStrokeRoman ;
|
||||
struct freeglutStrokeFont glutStrokeMonoRoman ;
|
||||
|
||||
struct freeglutBitmapFont glutBitmap9By15 ;
|
||||
struct freeglutBitmapFont glutBitmap8By13 ;
|
||||
struct freeglutBitmapFont glutBitmapTimesRoman10 ;
|
||||
struct freeglutBitmapFont glutBitmapTimesRoman24 ;
|
||||
struct freeglutBitmapFont glutBitmapHelvetica10 ;
|
||||
struct freeglutBitmapFont glutBitmapHelvetica12 ;
|
||||
struct freeglutBitmapFont glutBitmapHelvetica18 ;
|
||||
|
||||
#endif
|
||||
|
1180
examples/opengl-framework/freeglut/freeglut_init.c
Normal file
1180
examples/opengl-framework/freeglut/freeglut_init.c
Normal file
File diff suppressed because it is too large
Load Diff
378
examples/opengl-framework/freeglut/freeglut_input_devices.c
Normal file
378
examples/opengl-framework/freeglut/freeglut_input_devices.c
Normal file
|
@ -0,0 +1,378 @@
|
|||
/*
|
||||
* freeglut_input_devices.c
|
||||
*
|
||||
* Handles miscellaneous input devices via direct serial-port access.
|
||||
* Proper X11 XInput device support is not yet supported.
|
||||
* Also lacks Mac support.
|
||||
*
|
||||
* Written by Joe Krahn <krahn@niehs.nih.gov> 2005
|
||||
*
|
||||
* Copyright (c) 2005 Stephen J. Baker. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
typedef struct {
|
||||
int fd;
|
||||
struct termios termio, termio_save;
|
||||
} SERIALPORT;
|
||||
|
||||
#elif TARGET_HOST_MS_WINDOWS
|
||||
#include <sys/types.h>
|
||||
#include <winbase.h>
|
||||
typedef struct {
|
||||
HANDLE fh;
|
||||
COMMTIMEOUTS timeouts_save;
|
||||
DCB dcb_save;
|
||||
} SERIALPORT;
|
||||
|
||||
#endif
|
||||
|
||||
/********************* Dialbox definitions ***********************/
|
||||
|
||||
#define DIAL_NUM_VALUATORS 8
|
||||
|
||||
/* dial parser state machine states */
|
||||
#define DIAL_NEW (-1)
|
||||
#define DIAL_WHICH_DEVICE 0
|
||||
#define DIAL_VALUE_HIGH 1
|
||||
#define DIAL_VALUE_LOW 2
|
||||
|
||||
/* dial/button box commands */
|
||||
#define DIAL_INITIALIZE 0x20
|
||||
#define DIAL_SET_LEDS 0x75
|
||||
#define DIAL_SET_TEXT 0x61
|
||||
#define DIAL_SET_AUTO_DIALS 0x50
|
||||
#define DIAL_SET_AUTO_DELTA_DIALS 0x51
|
||||
#define DIAL_SET_FILTER 0x53
|
||||
#define DIAL_SET_BUTTONS_MOM_TYPE 0x71
|
||||
#define DIAL_SET_AUTO_MOM_BUTTONS 0x73
|
||||
#define DIAL_SET_ALL_LEDS 0x4b
|
||||
#define DIAL_CLEAR_ALL_LEDS 0x4c
|
||||
|
||||
/* dial/button box replies and events */
|
||||
#define DIAL_INITIALIZED 0x20
|
||||
#define DIAL_BASE 0x30
|
||||
#define DIAL_DELTA_BASE 0x40
|
||||
#define DIAL_PRESS_BASE 0xc0
|
||||
#define DIAL_RELEASE_BASE 0xe0
|
||||
|
||||
/* macros to determine reply type */
|
||||
#define IS_DIAL_EVENT(ch) (((ch)>=DIAL_BASE)&&((ch)<DIAL_BASE+DIAL_NUM_VALUATORS))
|
||||
#define IS_KEY_PRESS(ch) (((ch)>=DIAL_PRESS_BASE)&&((ch)<DIAL_PRESS_BASE+DIAL_NUM_BUTTONS))
|
||||
#define IS_KEY_RELEASE(ch) (((ch)>=DIAL_RELEASE_BASE)&&((ch)<DIAL_RELEASE_BASE+DIAL_NUM_BUTTONS))
|
||||
#define IS_INIT_EVENT(ch) ((ch)==DIAL_INITIALIZED)
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
static SERIALPORT *serial_open ( const char *device );
|
||||
static void serial_close ( SERIALPORT *port );
|
||||
static int serial_getchar ( SERIALPORT *port );
|
||||
static int serial_putchar ( SERIALPORT *port, unsigned char ch );
|
||||
static void serial_flush ( SERIALPORT *port );
|
||||
|
||||
static void send_dial_event(int dial, int value);
|
||||
static void poll_dials(int id);
|
||||
|
||||
/* local variables */
|
||||
static SERIALPORT *dialbox_port=NULL;
|
||||
|
||||
/*****************************************************************/
|
||||
|
||||
/*
|
||||
* Implementation for glutDeviceGet(GLUT_HAS_DIAL_AND_BUTTON_BOX)
|
||||
*/
|
||||
int fgInputDeviceDetect( void )
|
||||
{
|
||||
fgInitialiseInputDevices ();
|
||||
|
||||
if ( !dialbox_port )
|
||||
return 0;
|
||||
|
||||
if ( !fgState.InputDevsInitialised )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try initializing the input device(s)
|
||||
*/
|
||||
void fgInitialiseInputDevices ( void )
|
||||
{
|
||||
if( !fgState.InputDevsInitialised )
|
||||
{
|
||||
const char *dial_device=NULL;
|
||||
dial_device = getenv ( "GLUT_DIALS_SERIAL" );
|
||||
#if TARGET_HOST_MS_WINDOWS
|
||||
if (!dial_device){
|
||||
static char devname[256];
|
||||
DWORD size=sizeof(devname);
|
||||
DWORD type = REG_SZ;
|
||||
HKEY key;
|
||||
if (RegOpenKeyA(HKEY_LOCAL_MACHINE,"SOFTWARE\\FreeGLUT",&key)==ERROR_SUCCESS) {
|
||||
if (RegQueryValueExA(key,"DialboxSerialPort",NULL,&type,(LPBYTE)devname,&size)==ERROR_SUCCESS){
|
||||
dial_device=devname;
|
||||
}
|
||||
RegCloseKey(key);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if ( !dial_device ) return;
|
||||
if ( !( dialbox_port = serial_open ( dial_device ) ) ) return;
|
||||
serial_putchar(dialbox_port,DIAL_INITIALIZE);
|
||||
glutTimerFunc ( 10, poll_dials, 0 );
|
||||
fgState.InputDevsInitialised = GL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void fgInputDeviceClose( void )
|
||||
{
|
||||
if ( fgState.InputDevsInitialised )
|
||||
{
|
||||
serial_close ( dialbox_port );
|
||||
dialbox_port = NULL;
|
||||
fgState.InputDevsInitialised = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
/* Check all windows for dialbox callbacks */
|
||||
static void fghcbEnumDialCallbacks ( SFG_Window *window, SFG_Enumerator *enumerator )
|
||||
{
|
||||
/* Built-in to INVOKE_WCB(): if window->Callbacks[CB_Dials] */
|
||||
INVOKE_WCB ( *window,Dials, ( ((int*)enumerator->data)[0], ((int*)enumerator->data)[1]) );
|
||||
fgEnumSubWindows ( window, fghcbEnumDialCallbacks, enumerator );
|
||||
}
|
||||
|
||||
static void send_dial_event ( int num, int value )
|
||||
{
|
||||
SFG_Enumerator enumerator;
|
||||
int data[2];
|
||||
data[0] = num;
|
||||
data[1] = value;
|
||||
enumerator.found = GL_FALSE;
|
||||
enumerator.data = data;
|
||||
fgEnumWindows ( fghcbEnumDialCallbacks, &enumerator );
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
static void poll_dials ( int id )
|
||||
{
|
||||
int data;
|
||||
static int dial_state = DIAL_NEW;
|
||||
static int dial_which;
|
||||
static int dial_value;
|
||||
static int dials[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
if ( !dialbox_port ) return;
|
||||
|
||||
while ( (data=serial_getchar(dialbox_port)) != EOF )
|
||||
{
|
||||
if ( ( dial_state > DIAL_WHICH_DEVICE ) || IS_DIAL_EVENT ( data ) )
|
||||
{
|
||||
switch ( dial_state )
|
||||
{
|
||||
case DIAL_WHICH_DEVICE:
|
||||
dial_which = data - DIAL_BASE;
|
||||
dial_state++;
|
||||
break;
|
||||
case DIAL_VALUE_HIGH:
|
||||
dial_value = ( data << 8 );
|
||||
dial_state++;
|
||||
break;
|
||||
case DIAL_VALUE_LOW:
|
||||
dial_value |= data;
|
||||
if ( dial_value & 0x8000 ) dial_value -= 0x10000;
|
||||
dials[dial_which] = dial_value;
|
||||
send_dial_event ( dial_which + 1, dial_value * 360 / 256 );
|
||||
dial_state = DIAL_WHICH_DEVICE;
|
||||
break;
|
||||
default:
|
||||
/* error: Impossible state value! */
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( data == DIAL_INITIALIZED )
|
||||
{
|
||||
fgState.InputDevsInitialised = GL_TRUE;
|
||||
dial_state = DIAL_WHICH_DEVICE;
|
||||
serial_putchar(dialbox_port,DIAL_SET_AUTO_DIALS);
|
||||
serial_putchar(dialbox_port,0xff);
|
||||
serial_putchar(dialbox_port,0xff);
|
||||
}
|
||||
else /* Unknown data; try flushing. */
|
||||
serial_flush(dialbox_port);
|
||||
}
|
||||
|
||||
glutTimerFunc ( 2, poll_dials, 0 );
|
||||
}
|
||||
|
||||
|
||||
/******** OS Specific Serial I/O routines *******/
|
||||
#if TARGET_HOST_POSIX_X11 /* ==> Linux/BSD/UNIX POSIX serial I/O */
|
||||
static SERIALPORT *serial_open ( const char *device )
|
||||
{
|
||||
int fd;
|
||||
struct termios termio;
|
||||
SERIALPORT *port;
|
||||
|
||||
fd = open(device, O_RDWR | O_NONBLOCK );
|
||||
if (fd <0) {
|
||||
perror(device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
port = malloc(sizeof(SERIALPORT));
|
||||
memset(port, 0, sizeof(SERIALPORT));
|
||||
port->fd = fd;
|
||||
|
||||
/* save current port settings */
|
||||
tcgetattr(fd,&port->termio_save);
|
||||
|
||||
memset(&termio, 0, sizeof(termio));
|
||||
termio.c_cflag = CS8 | CREAD | HUPCL ;
|
||||
termio.c_iflag = IGNPAR | IGNBRK ;
|
||||
termio.c_cc[VTIME] = 0; /* inter-character timer */
|
||||
termio.c_cc[VMIN] = 1; /* block read until 1 chars received, when blocking I/O */
|
||||
|
||||
cfsetispeed(&termio, B9600);
|
||||
cfsetospeed(&termio, B9600);
|
||||
tcsetattr(fd,TCSANOW,&termio);
|
||||
|
||||
serial_flush(port);
|
||||
return port;
|
||||
}
|
||||
|
||||
static void serial_close(SERIALPORT *port)
|
||||
{
|
||||
if (port)
|
||||
{
|
||||
/* restore old port settings */
|
||||
tcsetattr(port->fd,TCSANOW,&port->termio_save);
|
||||
close(port->fd);
|
||||
free(port);
|
||||
}
|
||||
}
|
||||
|
||||
static int serial_getchar(SERIALPORT *port)
|
||||
{
|
||||
unsigned char ch;
|
||||
if (!port) return EOF;
|
||||
if (read(port->fd,&ch,1)) return ch;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
static int serial_putchar(SERIALPORT *port, unsigned char ch){
|
||||
if (!port) return 0;
|
||||
return write(port->fd,&ch,1);
|
||||
}
|
||||
|
||||
static void serial_flush ( SERIALPORT *port )
|
||||
{
|
||||
tcflush ( port->fd, TCIOFLUSH );
|
||||
}
|
||||
|
||||
#elif TARGET_HOST_MS_WINDOWS
|
||||
|
||||
static SERIALPORT *serial_open(const char *device){
|
||||
HANDLE fh;
|
||||
DCB dcb={sizeof(DCB)};
|
||||
COMMTIMEOUTS timeouts;
|
||||
SERIALPORT *port;
|
||||
|
||||
fh = CreateFile(device,GENERIC_READ|GENERIC_WRITE,0,NULL,
|
||||
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
|
||||
if (!fh) return NULL;
|
||||
|
||||
port = malloc(sizeof(SERIALPORT));
|
||||
ZeroMemory(port, sizeof(SERIALPORT));
|
||||
port->fh = fh;
|
||||
|
||||
/* save current port settings */
|
||||
GetCommState(fh,&port->dcb_save);
|
||||
GetCommTimeouts(fh,&port->timeouts_save);
|
||||
|
||||
dcb.DCBlength=sizeof(DCB);
|
||||
BuildCommDCB("96,n,8,1",&dcb);
|
||||
SetCommState(fh,&dcb);
|
||||
|
||||
ZeroMemory(&timeouts,sizeof(timeouts));
|
||||
timeouts.ReadTotalTimeoutConstant=1;
|
||||
timeouts.WriteTotalTimeoutConstant=1;
|
||||
SetCommTimeouts(fh,&timeouts);
|
||||
|
||||
serial_flush(port);
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
static void serial_close(SERIALPORT *port){
|
||||
if (port){
|
||||
/* restore old port settings */
|
||||
SetCommState(port->fh,&port->dcb_save);
|
||||
SetCommTimeouts(port->fh,&port->timeouts_save);
|
||||
CloseHandle(port->fh);
|
||||
free(port);
|
||||
}
|
||||
}
|
||||
|
||||
static int serial_getchar(SERIALPORT *port){
|
||||
DWORD n;
|
||||
unsigned char ch;
|
||||
if (!port) return EOF;
|
||||
if (!ReadFile(port->fh,&ch,1,&n,NULL)) return EOF;
|
||||
if (n==1) return ch;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
static int serial_putchar(SERIALPORT *port, unsigned char ch){
|
||||
DWORD n;
|
||||
if (!port) return 0;
|
||||
return WriteFile(port->fh,&ch,1,&n,NULL);
|
||||
}
|
||||
|
||||
static void serial_flush ( SERIALPORT *port )
|
||||
{
|
||||
FlushFileBuffers(port->fh);
|
||||
}
|
||||
|
||||
#endif
|
1023
examples/opengl-framework/freeglut/freeglut_internal.h
Normal file
1023
examples/opengl-framework/freeglut/freeglut_internal.h
Normal file
File diff suppressed because it is too large
Load Diff
1800
examples/opengl-framework/freeglut/freeglut_joystick.c
Normal file
1800
examples/opengl-framework/freeglut/freeglut_joystick.c
Normal file
File diff suppressed because it is too large
Load Diff
2511
examples/opengl-framework/freeglut/freeglut_main.c
Normal file
2511
examples/opengl-framework/freeglut/freeglut_main.c
Normal file
File diff suppressed because it is too large
Load Diff
1002
examples/opengl-framework/freeglut/freeglut_menu.c
Normal file
1002
examples/opengl-framework/freeglut/freeglut_menu.c
Normal file
File diff suppressed because it is too large
Load Diff
214
examples/opengl-framework/freeglut/freeglut_misc.c
Normal file
214
examples/opengl-framework/freeglut/freeglut_misc.c
Normal file
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* freeglut_misc.c
|
||||
*
|
||||
* Functions that didn't fit anywhere else...
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Thu Dec 9 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.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
/*
|
||||
* TODO BEFORE THE STABLE RELEASE:
|
||||
*
|
||||
* glutSetColor() --
|
||||
* glutGetColor() --
|
||||
* glutCopyColormap() --
|
||||
* glutSetKeyRepeat() -- this is evil and should be removed from API
|
||||
*/
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* This functions checks if an OpenGL extension is supported or not
|
||||
*
|
||||
* XXX Wouldn't this be simpler and clearer if we used strtok()?
|
||||
*/
|
||||
int FGAPIENTRY glutExtensionSupported( const char* extension )
|
||||
{
|
||||
const char *extensions, *start;
|
||||
const size_t len = strlen( extension );
|
||||
|
||||
/* Make sure there is a current window, and thus a current context available */
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutExtensionSupported" );
|
||||
freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 );
|
||||
|
||||
if (strchr(extension, ' '))
|
||||
return 0;
|
||||
start = extensions = (const char *) glGetString(GL_EXTENSIONS);
|
||||
|
||||
/* XXX consider printing a warning to stderr that there's no current
|
||||
* rendering context.
|
||||
*/
|
||||
freeglut_return_val_if_fail( extensions != NULL, 0 );
|
||||
|
||||
while (1) {
|
||||
const char *p = strstr(extensions, extension);
|
||||
if (!p)
|
||||
return 0; /* not found */
|
||||
/* check that the match isn't a super string */
|
||||
if ((p == start || p[-1] == ' ') && (p[len] == ' ' || p[len] == 0))
|
||||
return 1;
|
||||
/* skip the false match and continue */
|
||||
extensions = p + len;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#ifndef GL_INVALID_FRAMEBUFFER_OPERATION
|
||||
#ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT
|
||||
#define GL_INVALID_FRAMEBUFFER_OPERATION GL_INVALID_FRAMEBUFFER_OPERATION_EXT
|
||||
#else
|
||||
#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GL_TABLE_TOO_LARGE
|
||||
#ifdef GL_TABLE_TOO_LARGE_EXT
|
||||
#define GL_TABLE_TOO_LARGE GL_TABLE_TOO_LARGE_EXT
|
||||
#else
|
||||
#define GL_TABLE_TOO_LARGE 0x8031
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GL_TEXTURE_TOO_LARGE
|
||||
#ifdef GL_TEXTURE_TOO_LARGE_EXT
|
||||
#define GL_TEXTURE_TOO_LARGE GL_TEXTURE_TOO_LARGE_EXT
|
||||
#else
|
||||
#define GL_TEXTURE_TOO_LARGE 0x8065
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A cut-down local version of gluErrorString to avoid depending on GLU.
|
||||
*/
|
||||
static const char* fghErrorString( GLenum error )
|
||||
{
|
||||
switch ( error ) {
|
||||
case GL_INVALID_ENUM: return "invalid enumerant";
|
||||
case GL_INVALID_VALUE: return "invalid value";
|
||||
case GL_INVALID_OPERATION: return "invalid operation";
|
||||
case GL_STACK_OVERFLOW: return "stack overflow";
|
||||
case GL_STACK_UNDERFLOW: return "stack underflow";
|
||||
case GL_OUT_OF_MEMORY: return "out of memory";
|
||||
case GL_TABLE_TOO_LARGE: return "table too large";
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION: return "invalid framebuffer operation";
|
||||
case GL_TEXTURE_TOO_LARGE: return "texture too large";
|
||||
default: return "unknown GL error";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function reports all the OpenGL errors that happened till now
|
||||
*/
|
||||
void FGAPIENTRY glutReportErrors( void )
|
||||
{
|
||||
GLenum error;
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutReportErrors" );
|
||||
while( ( error = glGetError() ) != GL_NO_ERROR )
|
||||
fgWarning( "GL error: %s", fghErrorString( error ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Control the auto-repeat of keystrokes to the current window
|
||||
*/
|
||||
void FGAPIENTRY glutIgnoreKeyRepeat( int ignore )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIgnoreKeyRepeat" );
|
||||
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutIgnoreKeyRepeat" );
|
||||
|
||||
fgStructure.CurrentWindow->State.IgnoreKeyRepeat = ignore ? GL_TRUE : GL_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set global auto-repeat of keystrokes
|
||||
*
|
||||
* RepeatMode should be either:
|
||||
* GLUT_KEY_REPEAT_OFF
|
||||
* GLUT_KEY_REPEAT_ON
|
||||
* GLUT_KEY_REPEAT_DEFAULT
|
||||
*/
|
||||
void FGAPIENTRY glutSetKeyRepeat( int repeatMode )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetKeyRepeat" );
|
||||
|
||||
switch( repeatMode )
|
||||
{
|
||||
case GLUT_KEY_REPEAT_OFF:
|
||||
case GLUT_KEY_REPEAT_ON:
|
||||
fgState.KeyRepeat = repeatMode;
|
||||
break;
|
||||
|
||||
case GLUT_KEY_REPEAT_DEFAULT:
|
||||
fgState.KeyRepeat = GLUT_KEY_REPEAT_ON;
|
||||
break;
|
||||
|
||||
default:
|
||||
fgError ("Invalid glutSetKeyRepeat mode: %d", repeatMode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Forces the joystick callback to be executed
|
||||
*/
|
||||
void FGAPIENTRY glutForceJoystickFunc( void )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutForceJoystickFunc" );
|
||||
#if !defined(_WIN32_WCE)
|
||||
freeglut_return_if_fail( fgStructure.CurrentWindow != NULL );
|
||||
freeglut_return_if_fail( FETCH_WCB( *( fgStructure.CurrentWindow ), Joystick ) );
|
||||
fgJoystickPollWindow( fgStructure.CurrentWindow );
|
||||
#endif /* !defined(_WIN32_WCE) */
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void FGAPIENTRY glutSetColor( int nColor, GLfloat red, GLfloat green, GLfloat blue )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetColor" );
|
||||
/* We really need to do something here. */
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
GLfloat FGAPIENTRY glutGetColor( int color, int component )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetColor" );
|
||||
/* We really need to do something here. */
|
||||
return( 0.0f );
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void FGAPIENTRY glutCopyColormap( int window )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutCopyColormap" );
|
||||
/* We really need to do something here. */
|
||||
}
|
||||
|
||||
/*** END OF FILE ***/
|
45
examples/opengl-framework/freeglut/freeglut_overlay.c
Normal file
45
examples/opengl-framework/freeglut/freeglut_overlay.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* freeglut_overlay.c
|
||||
*
|
||||
* Overlay management functions (as defined by GLUT API)
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Thu Dec 16 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.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
/*
|
||||
* NOTE: functions declared in this file probably will not be implemented.
|
||||
*/
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
void FGAPIENTRY glutEstablishOverlay( void ) { /* Not implemented */ }
|
||||
void FGAPIENTRY glutRemoveOverlay( void ) { /* Not implemented */ }
|
||||
void FGAPIENTRY glutUseLayer( GLenum layer ) { /* Not implemented */ }
|
||||
void FGAPIENTRY glutPostOverlayRedisplay( void ) { /* Not implemented */ }
|
||||
void FGAPIENTRY glutPostWindowOverlayRedisplay( int ID ) { /* Not implemented */ }
|
||||
void FGAPIENTRY glutShowOverlay( void ) { /* Not implemented */ }
|
||||
void FGAPIENTRY glutHideOverlay( void ) { /* Not implemented */ }
|
||||
|
||||
/*** END OF FILE ***/
|
471
examples/opengl-framework/freeglut/freeglut_spaceball.c
Normal file
471
examples/opengl-framework/freeglut/freeglut_spaceball.c
Normal file
|
@ -0,0 +1,471 @@
|
|||
/* Spaceball support for Linux.
|
||||
* Written by John Tsiombikas <nuclear@member.fsf.org>
|
||||
*
|
||||
* This code supports 3Dconnexion's 6-dof space-whatever devices.
|
||||
* It can communicate with either the proprietary 3Dconnexion daemon (3dxsrv)
|
||||
* free spacenavd (http://spacenav.sourceforge.net), through the "standard"
|
||||
* magellan X-based protocol.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
/* -- PRIVATE FUNCTIONS --------------------------------------------------- */
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
enum {
|
||||
SPNAV_EVENT_ANY, /* used by spnav_remove_events() */
|
||||
SPNAV_EVENT_MOTION,
|
||||
SPNAV_EVENT_BUTTON /* includes both press and release */
|
||||
};
|
||||
|
||||
struct spnav_event_motion {
|
||||
int type;
|
||||
int x, y, z;
|
||||
int rx, ry, rz;
|
||||
unsigned int period;
|
||||
int *data;
|
||||
};
|
||||
|
||||
struct spnav_event_button {
|
||||
int type;
|
||||
int press;
|
||||
int bnum;
|
||||
};
|
||||
|
||||
typedef union spnav_event {
|
||||
int type;
|
||||
struct spnav_event_motion motion;
|
||||
struct spnav_event_button button;
|
||||
} spnav_event;
|
||||
|
||||
|
||||
static int spnav_x11_open(Display *dpy, Window win);
|
||||
static int spnav_x11_window(Window win);
|
||||
static int spnav_x11_event(const XEvent *xev, spnav_event *event);
|
||||
static int spnav_close(void);
|
||||
static int spnav_fd(void);
|
||||
static int spnav_remove_events(int type);
|
||||
|
||||
static SFG_Window *spnav_win;
|
||||
#endif
|
||||
|
||||
/* Flag telling whether we have a spaceball:
|
||||
* 0 - haven't tried initializing
|
||||
* 1 - have successfully initialized
|
||||
* -1 - have tried to initialize but not succeeded
|
||||
*/
|
||||
static int sball_initialized = 0;
|
||||
|
||||
|
||||
void fgInitialiseSpaceball(void)
|
||||
{
|
||||
if(sball_initialized != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
{
|
||||
Window w;
|
||||
|
||||
if(!fgStructure.CurrentWindow)
|
||||
{
|
||||
sball_initialized = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
w = fgStructure.CurrentWindow->Window.Handle;
|
||||
if(spnav_x11_open(fgDisplay.Display, w) == -1)
|
||||
{
|
||||
sball_initialized = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
sball_initialized = 1;
|
||||
}
|
||||
|
||||
void fgSpaceballClose(void)
|
||||
{
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
spnav_close();
|
||||
#endif
|
||||
}
|
||||
|
||||
int fgHasSpaceball(void)
|
||||
{
|
||||
if(sball_initialized == 0) {
|
||||
fgInitialiseSpaceball();
|
||||
if(sball_initialized != 1) {
|
||||
fgWarning("fgInitialiseSpaceball failed\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
/* XXX this function should somehow query the driver if there's a device
|
||||
* plugged in, as opposed to just checking if there's a driver to talk to.
|
||||
*/
|
||||
return spnav_fd() == -1 ? 0 : 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int fgSpaceballNumButtons(void)
|
||||
{
|
||||
if(sball_initialized == 0) {
|
||||
fgInitialiseSpaceball();
|
||||
if(sball_initialized != 1) {
|
||||
fgWarning("fgInitialiseSpaceball failed\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
return 2; /* TODO implement this properly */
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fgSpaceballSetWindow(SFG_Window *window)
|
||||
{
|
||||
if(sball_initialized == 0) {
|
||||
fgInitialiseSpaceball();
|
||||
if(sball_initialized != 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
if(spnav_win != window) {
|
||||
spnav_x11_window(window->Window.Handle);
|
||||
spnav_win = window;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
int fgIsSpaceballXEvent(const XEvent *xev)
|
||||
{
|
||||
spnav_event sev;
|
||||
|
||||
if(spnav_win != fgStructure.CurrentWindow) {
|
||||
/* this will also initialize spaceball if needed (first call) */
|
||||
fgSpaceballSetWindow(fgStructure.CurrentWindow);
|
||||
}
|
||||
|
||||
if(sball_initialized != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return spnav_x11_event(xev, &sev);
|
||||
}
|
||||
|
||||
void fgSpaceballHandleXEvent(const XEvent *xev)
|
||||
{
|
||||
spnav_event sev;
|
||||
|
||||
if(sball_initialized == 0) {
|
||||
fgInitialiseSpaceball();
|
||||
if(sball_initialized != 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(spnav_x11_event(xev, &sev)) {
|
||||
switch(sev.type) {
|
||||
case SPNAV_EVENT_MOTION:
|
||||
if(sev.motion.x | sev.motion.y | sev.motion.z) {
|
||||
INVOKE_WCB(*spnav_win, SpaceMotion, (sev.motion.x, sev.motion.y, sev.motion.z));
|
||||
}
|
||||
if(sev.motion.rx | sev.motion.ry | sev.motion.rz) {
|
||||
INVOKE_WCB(*spnav_win, SpaceRotation, (sev.motion.rx, sev.motion.ry, sev.motion.rz));
|
||||
}
|
||||
spnav_remove_events(SPNAV_EVENT_MOTION);
|
||||
break;
|
||||
|
||||
case SPNAV_EVENT_BUTTON:
|
||||
INVOKE_WCB(*spnav_win, SpaceButton, (sev.button.bnum, sev.button.press ? GLUT_DOWN : GLUT_UP));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
The following code is part of libspnav, part of the spacenav project (spacenav.sf.net)
|
||||
Copyright (C) 2007-2009 John Tsiombikas <nuclear@member.fsf.org>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
static Window get_daemon_window(Display *dpy);
|
||||
static int catch_badwin(Display *dpy, XErrorEvent *err);
|
||||
|
||||
static Display *dpy;
|
||||
static Window app_win;
|
||||
static Atom motion_event, button_press_event, button_release_event, command_event;
|
||||
|
||||
enum {
|
||||
CMD_APP_WINDOW = 27695,
|
||||
CMD_APP_SENS
|
||||
};
|
||||
|
||||
#define IS_OPEN dpy
|
||||
|
||||
struct event_node {
|
||||
spnav_event event;
|
||||
struct event_node *next;
|
||||
};
|
||||
|
||||
static int spnav_x11_open(Display *display, Window win)
|
||||
{
|
||||
if(IS_OPEN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dpy = display;
|
||||
|
||||
motion_event = XInternAtom(dpy, "MotionEvent", True);
|
||||
button_press_event = XInternAtom(dpy, "ButtonPressEvent", True);
|
||||
button_release_event = XInternAtom(dpy, "ButtonReleaseEvent", True);
|
||||
command_event = XInternAtom(dpy, "CommandEvent", True);
|
||||
|
||||
if(!motion_event || !button_press_event || !button_release_event || !command_event) {
|
||||
dpy = 0;
|
||||
return -1; /* daemon not started */
|
||||
}
|
||||
|
||||
if(spnav_x11_window(win) == -1) {
|
||||
dpy = 0;
|
||||
return -1; /* daemon not started */
|
||||
}
|
||||
|
||||
app_win = win;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spnav_close(void)
|
||||
{
|
||||
if(dpy) {
|
||||
spnav_x11_window(DefaultRootWindow(dpy));
|
||||
app_win = 0;
|
||||
dpy = 0;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int spnav_x11_window(Window win)
|
||||
{
|
||||
int (*prev_xerr_handler)(Display*, XErrorEvent*);
|
||||
XEvent xev;
|
||||
Window daemon_win;
|
||||
|
||||
if(!IS_OPEN) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!(daemon_win = get_daemon_window(dpy))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
prev_xerr_handler = XSetErrorHandler(catch_badwin);
|
||||
|
||||
xev.type = ClientMessage;
|
||||
xev.xclient.send_event = False;
|
||||
xev.xclient.display = dpy;
|
||||
xev.xclient.window = win;
|
||||
xev.xclient.message_type = command_event;
|
||||
xev.xclient.format = 16;
|
||||
xev.xclient.data.s[0] = ((unsigned int)win & 0xffff0000) >> 16;
|
||||
xev.xclient.data.s[1] = (unsigned int)win & 0xffff;
|
||||
xev.xclient.data.s[2] = CMD_APP_WINDOW;
|
||||
|
||||
XSendEvent(dpy, daemon_win, False, 0, &xev);
|
||||
XSync(dpy, False);
|
||||
|
||||
XSetErrorHandler(prev_xerr_handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spnav_fd(void)
|
||||
{
|
||||
if(dpy) {
|
||||
return ConnectionNumber(dpy);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*static int spnav_wait_event(spnav_event *event)
|
||||
{
|
||||
if(dpy) {
|
||||
for(;;) {
|
||||
XEvent xev;
|
||||
XNextEvent(dpy, &xev);
|
||||
|
||||
if(spnav_x11_event(&xev, event) > 0) {
|
||||
return event->type;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spnav_poll_event(spnav_event *event)
|
||||
{
|
||||
if(dpy) {
|
||||
if(XPending(dpy)) {
|
||||
XEvent xev;
|
||||
XNextEvent(dpy, &xev);
|
||||
|
||||
return spnav_x11_event(&xev, event);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
static Bool match_events(Display *dpy, XEvent *xev, char *arg)
|
||||
{
|
||||
int evtype = *(int*)arg;
|
||||
|
||||
if(xev->type != ClientMessage) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if(xev->xclient.message_type == motion_event) {
|
||||
return !evtype || evtype == SPNAV_EVENT_MOTION ? True : False;
|
||||
}
|
||||
if(xev->xclient.message_type == button_press_event ||
|
||||
xev->xclient.message_type == button_release_event) {
|
||||
return !evtype || evtype == SPNAV_EVENT_BUTTON ? True : False;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static int spnav_remove_events(int type)
|
||||
{
|
||||
int rm_count = 0;
|
||||
|
||||
if(dpy) {
|
||||
XEvent xev;
|
||||
|
||||
while(XCheckIfEvent(dpy, &xev, match_events, (char*)&type)) {
|
||||
rm_count++;
|
||||
}
|
||||
return rm_count;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spnav_x11_event(const XEvent *xev, spnav_event *event)
|
||||
{
|
||||
int i;
|
||||
int xmsg_type;
|
||||
|
||||
if(xev->type != ClientMessage) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
xmsg_type = xev->xclient.message_type;
|
||||
|
||||
if(xmsg_type != motion_event && xmsg_type != button_press_event &&
|
||||
xmsg_type != button_release_event) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(xmsg_type == motion_event) {
|
||||
event->type = SPNAV_EVENT_MOTION;
|
||||
event->motion.data = &event->motion.x;
|
||||
|
||||
for(i=0; i<6; i++) {
|
||||
event->motion.data[i] = xev->xclient.data.s[i + 2];
|
||||
}
|
||||
event->motion.period = xev->xclient.data.s[8];
|
||||
} else {
|
||||
event->type = SPNAV_EVENT_BUTTON;
|
||||
event->button.press = xmsg_type == button_press_event ? 1 : 0;
|
||||
event->button.bnum = xev->xclient.data.s[2];
|
||||
}
|
||||
return event->type;
|
||||
}
|
||||
|
||||
|
||||
static Window get_daemon_window(Display *dpy)
|
||||
{
|
||||
Window win, root_win;
|
||||
XTextProperty wname;
|
||||
Atom type;
|
||||
int fmt;
|
||||
unsigned long nitems, bytes_after;
|
||||
unsigned char *prop;
|
||||
|
||||
root_win = DefaultRootWindow(dpy);
|
||||
|
||||
XGetWindowProperty(dpy, root_win, command_event, 0, 1, False, AnyPropertyType, &type, &fmt, &nitems, &bytes_after, &prop);
|
||||
if(!prop) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
win = *(Window*)prop;
|
||||
XFree(prop);
|
||||
|
||||
if(!XGetWMName(dpy, win, &wname) || strcmp("Magellan Window", (char*)wname.value) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return win;
|
||||
}
|
||||
|
||||
static int catch_badwin(Display *dpy, XErrorEvent *err)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
if(err->error_code == BadWindow) {
|
||||
/* do nothing? */
|
||||
} else {
|
||||
XGetErrorText(dpy, err->error_code, buf, sizeof buf);
|
||||
fprintf(stderr, "Caught unexpected X error: %s\n", buf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* TARGET_HOST_POSIX_X11 */
|
887
examples/opengl-framework/freeglut/freeglut_state.c
Normal file
887
examples/opengl-framework/freeglut/freeglut_state.c
Normal file
|
@ -0,0 +1,887 @@
|
|||
/*
|
||||
* freeglut_state.c
|
||||
*
|
||||
* Freeglut state query methods.
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Thu Dec 16 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.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
/*
|
||||
* TODO BEFORE THE STABLE RELEASE:
|
||||
*
|
||||
* glutGet() -- X11 tests passed, but check if all enums
|
||||
* handled (what about Win32?)
|
||||
* glutDeviceGet() -- X11 tests passed, but check if all enums
|
||||
* handled (what about Win32?)
|
||||
* glutGetModifiers() -- OK, but could also remove the limitation
|
||||
* glutLayerGet() -- what about GLUT_NORMAL_DAMAGED?
|
||||
*
|
||||
* The fail-on-call policy will help adding the most needed things imho.
|
||||
*/
|
||||
|
||||
/* -- LOCAL DEFINITIONS ---------------------------------------------------- */
|
||||
|
||||
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
/*
|
||||
* Queries the GL context about some attributes
|
||||
*/
|
||||
static int fghGetConfig( int attribute )
|
||||
{
|
||||
int returnValue = 0;
|
||||
int result; /* Not checked */
|
||||
|
||||
if( fgStructure.CurrentWindow )
|
||||
result = glXGetFBConfigAttrib( fgDisplay.Display,
|
||||
*(fgStructure.CurrentWindow->Window.FBConfig),
|
||||
attribute,
|
||||
&returnValue );
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* General settings assignment method
|
||||
*/
|
||||
void FGAPIENTRY glutSetOption( GLenum eWhat, int value )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSetOption" );
|
||||
|
||||
/*
|
||||
* XXX In chronological code add order. (WHY in that order?)
|
||||
*/
|
||||
switch( eWhat )
|
||||
{
|
||||
case GLUT_INIT_WINDOW_X:
|
||||
fgState.Position.X = (GLint)value;
|
||||
break;
|
||||
|
||||
case GLUT_INIT_WINDOW_Y:
|
||||
fgState.Position.Y = (GLint)value;
|
||||
break;
|
||||
|
||||
case GLUT_INIT_WINDOW_WIDTH:
|
||||
fgState.Size.X = (GLint)value;
|
||||
break;
|
||||
|
||||
case GLUT_INIT_WINDOW_HEIGHT:
|
||||
fgState.Size.Y = (GLint)value;
|
||||
break;
|
||||
|
||||
case GLUT_INIT_DISPLAY_MODE:
|
||||
fgState.DisplayMode = (unsigned int)value;
|
||||
break;
|
||||
|
||||
case GLUT_ACTION_ON_WINDOW_CLOSE:
|
||||
fgState.ActionOnWindowClose = value;
|
||||
break;
|
||||
|
||||
case GLUT_RENDERING_CONTEXT:
|
||||
fgState.UseCurrentContext =
|
||||
( value == GLUT_USE_CURRENT_CONTEXT ) ? GL_TRUE : GL_FALSE;
|
||||
break;
|
||||
|
||||
case GLUT_DIRECT_RENDERING:
|
||||
fgState.DirectContext = value;
|
||||
break;
|
||||
|
||||
case GLUT_WINDOW_CURSOR:
|
||||
if( fgStructure.CurrentWindow != NULL )
|
||||
fgStructure.CurrentWindow->State.Cursor = value;
|
||||
break;
|
||||
|
||||
case GLUT_AUX:
|
||||
fgState.AuxiliaryBufferNumber = value;
|
||||
break;
|
||||
|
||||
case GLUT_MULTISAMPLE:
|
||||
fgState.SampleNumber = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
fgWarning( "glutSetOption(): missing enum handle %d", eWhat );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_HOST_MS_WINDOWS
|
||||
/* The following include file is available from SGI but is not standard:
|
||||
* #include <GL/wglext.h>
|
||||
* So we copy the necessary parts out of it to support the multisampling query
|
||||
*/
|
||||
#define WGL_SAMPLES_ARB 0x2042
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* General settings query method
|
||||
*/
|
||||
int FGAPIENTRY glutGet( GLenum eWhat )
|
||||
{
|
||||
#if TARGET_HOST_MS_WINDOWS
|
||||
int returnValue ;
|
||||
GLboolean boolValue ;
|
||||
#endif
|
||||
|
||||
int nsamples = 0;
|
||||
|
||||
switch (eWhat)
|
||||
{
|
||||
case GLUT_INIT_STATE:
|
||||
return fgState.Initialised;
|
||||
|
||||
case GLUT_ELAPSED_TIME:
|
||||
return fgElapsedTime();
|
||||
}
|
||||
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGet" );
|
||||
|
||||
/* XXX In chronological code add order. (WHY in that order?) */
|
||||
switch( eWhat )
|
||||
{
|
||||
/* Following values are stored in fgState and fgDisplay global structures */
|
||||
case GLUT_SCREEN_WIDTH: return fgDisplay.ScreenWidth ;
|
||||
case GLUT_SCREEN_HEIGHT: return fgDisplay.ScreenHeight ;
|
||||
case GLUT_SCREEN_WIDTH_MM: return fgDisplay.ScreenWidthMM ;
|
||||
case GLUT_SCREEN_HEIGHT_MM: return fgDisplay.ScreenHeightMM;
|
||||
case GLUT_INIT_WINDOW_X: return fgState.Position.Use ?
|
||||
fgState.Position.X : -1 ;
|
||||
case GLUT_INIT_WINDOW_Y: return fgState.Position.Use ?
|
||||
fgState.Position.Y : -1 ;
|
||||
case GLUT_INIT_WINDOW_WIDTH: return fgState.Size.Use ?
|
||||
fgState.Size.X : -1 ;
|
||||
case GLUT_INIT_WINDOW_HEIGHT: return fgState.Size.Use ?
|
||||
fgState.Size.Y : -1 ;
|
||||
case GLUT_INIT_DISPLAY_MODE: return fgState.DisplayMode ;
|
||||
case GLUT_INIT_MAJOR_VERSION: return fgState.MajorVersion ;
|
||||
case GLUT_INIT_MINOR_VERSION: return fgState.MinorVersion ;
|
||||
case GLUT_INIT_FLAGS: return fgState.ContextFlags ;
|
||||
case GLUT_INIT_PROFILE: return fgState.ContextProfile ;
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
/*
|
||||
* The window/context specific queries are handled mostly by
|
||||
* fghGetConfig().
|
||||
*/
|
||||
case GLUT_WINDOW_NUM_SAMPLES:
|
||||
#ifdef GLX_VERSION_1_3
|
||||
glGetIntegerv(GL_SAMPLES, &nsamples);
|
||||
#endif
|
||||
return nsamples;
|
||||
|
||||
/*
|
||||
* The rest of GLX queries under X are general enough to use a macro to
|
||||
* check them
|
||||
*/
|
||||
# define GLX_QUERY(a,b) case a: return fghGetConfig( b );
|
||||
|
||||
GLX_QUERY( GLUT_WINDOW_RGBA, GLX_RGBA );
|
||||
GLX_QUERY( GLUT_WINDOW_DOUBLEBUFFER, GLX_DOUBLEBUFFER );
|
||||
GLX_QUERY( GLUT_WINDOW_BUFFER_SIZE, GLX_BUFFER_SIZE );
|
||||
GLX_QUERY( GLUT_WINDOW_STENCIL_SIZE, GLX_STENCIL_SIZE );
|
||||
GLX_QUERY( GLUT_WINDOW_DEPTH_SIZE, GLX_DEPTH_SIZE );
|
||||
GLX_QUERY( GLUT_WINDOW_RED_SIZE, GLX_RED_SIZE );
|
||||
GLX_QUERY( GLUT_WINDOW_GREEN_SIZE, GLX_GREEN_SIZE );
|
||||
GLX_QUERY( GLUT_WINDOW_BLUE_SIZE, GLX_BLUE_SIZE );
|
||||
GLX_QUERY( GLUT_WINDOW_ALPHA_SIZE, GLX_ALPHA_SIZE );
|
||||
GLX_QUERY( GLUT_WINDOW_ACCUM_RED_SIZE, GLX_ACCUM_RED_SIZE );
|
||||
GLX_QUERY( GLUT_WINDOW_ACCUM_GREEN_SIZE, GLX_ACCUM_GREEN_SIZE );
|
||||
GLX_QUERY( GLUT_WINDOW_ACCUM_BLUE_SIZE, GLX_ACCUM_BLUE_SIZE );
|
||||
GLX_QUERY( GLUT_WINDOW_ACCUM_ALPHA_SIZE, GLX_ACCUM_ALPHA_SIZE );
|
||||
GLX_QUERY( GLUT_WINDOW_STEREO, GLX_STEREO );
|
||||
|
||||
# undef GLX_QUERY
|
||||
|
||||
/* Colormap size is handled in a bit different way than all the rest */
|
||||
case GLUT_WINDOW_COLORMAP_SIZE:
|
||||
if( (fghGetConfig( GLX_RGBA )) || (fgStructure.CurrentWindow == NULL) )
|
||||
{
|
||||
/*
|
||||
* We've got a RGBA visual, so there is no colormap at all.
|
||||
* The other possibility is that we have no current window set.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
const GLXFBConfig * fbconfig =
|
||||
fgStructure.CurrentWindow->Window.FBConfig;
|
||||
|
||||
XVisualInfo * visualInfo =
|
||||
glXGetVisualFromFBConfig( fgDisplay.Display, *fbconfig );
|
||||
|
||||
const int result = visualInfo->visual->map_entries;
|
||||
|
||||
XFree(visualInfo);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Those calls are somewhat similiar, as they use XGetWindowAttributes()
|
||||
* function
|
||||
*/
|
||||
case GLUT_WINDOW_X:
|
||||
case GLUT_WINDOW_Y:
|
||||
case GLUT_WINDOW_BORDER_WIDTH:
|
||||
case GLUT_WINDOW_HEADER_HEIGHT:
|
||||
{
|
||||
int x, y;
|
||||
Window w;
|
||||
|
||||
if( fgStructure.CurrentWindow == NULL )
|
||||
return 0;
|
||||
|
||||
XTranslateCoordinates(
|
||||
fgDisplay.Display,
|
||||
fgStructure.CurrentWindow->Window.Handle,
|
||||
fgDisplay.RootWindow,
|
||||
0, 0, &x, &y, &w);
|
||||
|
||||
switch ( eWhat )
|
||||
{
|
||||
case GLUT_WINDOW_X: return x;
|
||||
case GLUT_WINDOW_Y: return y;
|
||||
}
|
||||
|
||||
if ( w == 0 )
|
||||
return 0;
|
||||
XTranslateCoordinates(
|
||||
fgDisplay.Display,
|
||||
fgStructure.CurrentWindow->Window.Handle,
|
||||
w, 0, 0, &x, &y, &w);
|
||||
|
||||
switch ( eWhat )
|
||||
{
|
||||
case GLUT_WINDOW_BORDER_WIDTH: return x;
|
||||
case GLUT_WINDOW_HEADER_HEIGHT: return y;
|
||||
}
|
||||
}
|
||||
|
||||
case GLUT_WINDOW_WIDTH:
|
||||
case GLUT_WINDOW_HEIGHT:
|
||||
{
|
||||
XWindowAttributes winAttributes;
|
||||
|
||||
if( fgStructure.CurrentWindow == NULL )
|
||||
return 0;
|
||||
XGetWindowAttributes(
|
||||
fgDisplay.Display,
|
||||
fgStructure.CurrentWindow->Window.Handle,
|
||||
&winAttributes
|
||||
);
|
||||
switch ( eWhat )
|
||||
{
|
||||
case GLUT_WINDOW_WIDTH: return winAttributes.width ;
|
||||
case GLUT_WINDOW_HEIGHT: return winAttributes.height ;
|
||||
}
|
||||
}
|
||||
|
||||
/* I do not know yet if there will be a fgChooseVisual() function for Win32 */
|
||||
case GLUT_DISPLAY_MODE_POSSIBLE:
|
||||
{
|
||||
/* We should not have to call fgChooseFBConfig again here. */
|
||||
GLXFBConfig * fbconfig;
|
||||
int isPossible;
|
||||
|
||||
fbconfig = fgChooseFBConfig(NULL);
|
||||
|
||||
if (fbconfig == NULL)
|
||||
{
|
||||
isPossible = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
isPossible = 1;
|
||||
XFree(fbconfig);
|
||||
}
|
||||
|
||||
return isPossible;
|
||||
}
|
||||
|
||||
/* This is system-dependant */
|
||||
case GLUT_WINDOW_FORMAT_ID:
|
||||
if( fgStructure.CurrentWindow == NULL )
|
||||
return 0;
|
||||
|
||||
return fghGetConfig( GLX_VISUAL_ID );
|
||||
|
||||
#elif TARGET_HOST_MS_WINDOWS
|
||||
|
||||
case GLUT_WINDOW_NUM_SAMPLES:
|
||||
glGetIntegerv(WGL_SAMPLES_ARB, &nsamples);
|
||||
return nsamples;
|
||||
|
||||
/* Handle the OpenGL inquiries */
|
||||
case GLUT_WINDOW_RGBA:
|
||||
#if defined(_WIN32_WCE)
|
||||
boolValue = (GLboolean)0; /* WinCE doesn't support this feature */
|
||||
#else
|
||||
glGetBooleanv ( GL_RGBA_MODE, &boolValue );
|
||||
returnValue = boolValue ? 1 : 0;
|
||||
#endif
|
||||
return returnValue;
|
||||
case GLUT_WINDOW_DOUBLEBUFFER:
|
||||
#if defined(_WIN32_WCE)
|
||||
boolValue = (GLboolean)0; /* WinCE doesn't support this feature */
|
||||
#else
|
||||
glGetBooleanv ( GL_DOUBLEBUFFER, &boolValue );
|
||||
returnValue = boolValue ? 1 : 0;
|
||||
#endif
|
||||
return returnValue;
|
||||
case GLUT_WINDOW_STEREO:
|
||||
#if defined(_WIN32_WCE)
|
||||
boolValue = (GLboolean)0; /* WinCE doesn't support this feature */
|
||||
#else
|
||||
glGetBooleanv ( GL_STEREO, &boolValue );
|
||||
returnValue = boolValue ? 1 : 0;
|
||||
#endif
|
||||
return returnValue;
|
||||
|
||||
case GLUT_WINDOW_RED_SIZE:
|
||||
glGetIntegerv ( GL_RED_BITS, &returnValue );
|
||||
return returnValue;
|
||||
case GLUT_WINDOW_GREEN_SIZE:
|
||||
glGetIntegerv ( GL_GREEN_BITS, &returnValue );
|
||||
return returnValue;
|
||||
case GLUT_WINDOW_BLUE_SIZE:
|
||||
glGetIntegerv ( GL_BLUE_BITS, &returnValue );
|
||||
return returnValue;
|
||||
case GLUT_WINDOW_ALPHA_SIZE:
|
||||
glGetIntegerv ( GL_ALPHA_BITS, &returnValue );
|
||||
return returnValue;
|
||||
case GLUT_WINDOW_ACCUM_RED_SIZE:
|
||||
#if defined(_WIN32_WCE)
|
||||
returnValue = 0; /* WinCE doesn't support this feature */
|
||||
#else
|
||||
glGetIntegerv ( GL_ACCUM_RED_BITS, &returnValue );
|
||||
#endif
|
||||
return returnValue;
|
||||
case GLUT_WINDOW_ACCUM_GREEN_SIZE:
|
||||
#if defined(_WIN32_WCE)
|
||||
returnValue = 0; /* WinCE doesn't support this feature */
|
||||
#else
|
||||
glGetIntegerv ( GL_ACCUM_GREEN_BITS, &returnValue );
|
||||
#endif
|
||||
return returnValue;
|
||||
case GLUT_WINDOW_ACCUM_BLUE_SIZE:
|
||||
#if defined(_WIN32_WCE)
|
||||
returnValue = 0; /* WinCE doesn't support this feature */
|
||||
#else
|
||||
glGetIntegerv ( GL_ACCUM_BLUE_BITS, &returnValue );
|
||||
#endif
|
||||
return returnValue;
|
||||
case GLUT_WINDOW_ACCUM_ALPHA_SIZE:
|
||||
#if defined(_WIN32_WCE)
|
||||
returnValue = 0; /* WinCE doesn't support this feature */
|
||||
#else
|
||||
glGetIntegerv ( GL_ACCUM_ALPHA_BITS, &returnValue );
|
||||
#endif
|
||||
return returnValue;
|
||||
case GLUT_WINDOW_DEPTH_SIZE:
|
||||
glGetIntegerv ( GL_DEPTH_BITS, &returnValue );
|
||||
return returnValue;
|
||||
|
||||
case GLUT_WINDOW_BUFFER_SIZE:
|
||||
returnValue = 1 ; /* ????? */
|
||||
return returnValue;
|
||||
case GLUT_WINDOW_STENCIL_SIZE:
|
||||
returnValue = 0 ; /* ????? */
|
||||
return returnValue;
|
||||
|
||||
case GLUT_WINDOW_X:
|
||||
case GLUT_WINDOW_Y:
|
||||
case GLUT_WINDOW_WIDTH:
|
||||
case GLUT_WINDOW_HEIGHT:
|
||||
{
|
||||
/*
|
||||
* There is considerable confusion about the "right thing to
|
||||
* do" concerning window size and position. GLUT itself is
|
||||
* not consistent between Windows and UNIX/X11; since
|
||||
* platform independence is a virtue for "freeglut", we
|
||||
* decided to break with GLUT's behaviour.
|
||||
*
|
||||
* Under UNIX/X11, it is apparently not possible to get the
|
||||
* window border sizes in order to subtract them off the
|
||||
* window's initial position until some time after the window
|
||||
* has been created. Therefore we decided on the following
|
||||
* behaviour, both under Windows and under UNIX/X11:
|
||||
* - When you create a window with position (x,y) and size
|
||||
* (w,h), the upper left hand corner of the outside of the
|
||||
* window is at (x,y) and the size of the drawable area is
|
||||
* (w,h).
|
||||
* - When you query the size and position of the window--as
|
||||
* is happening here for Windows--"freeglut" will return
|
||||
* the size of the drawable area--the (w,h) that you
|
||||
* specified when you created the window--and the coordinates
|
||||
* of the upper left hand corner of the drawable
|
||||
* area--which is NOT the (x,y) you specified.
|
||||
*/
|
||||
|
||||
RECT winRect;
|
||||
|
||||
freeglut_return_val_if_fail( fgStructure.CurrentWindow != NULL, 0 );
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect );
|
||||
#else
|
||||
winRect = fghGetClientArea(fgStructure.CurrentWindow, FALSE);
|
||||
#endif /* defined(_WIN32_WCE) */
|
||||
|
||||
switch( eWhat )
|
||||
{
|
||||
case GLUT_WINDOW_X: return winRect.left ;
|
||||
case GLUT_WINDOW_Y: return winRect.top ;
|
||||
case GLUT_WINDOW_WIDTH: return winRect.right - winRect.left;
|
||||
case GLUT_WINDOW_HEIGHT: return winRect.bottom - winRect.top;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case GLUT_WINDOW_BORDER_WIDTH :
|
||||
case GLUT_WINDOW_HEADER_HEIGHT :
|
||||
#if defined(_WIN32_WCE)
|
||||
return 0;
|
||||
#else
|
||||
{
|
||||
DWORD windowStyle;
|
||||
|
||||
if (fgStructure.CurrentWindow && fgStructure.CurrentWindow->Window.Handle)
|
||||
windowStyle = GetWindowLong(fgStructure.CurrentWindow->Window.Handle, GWL_STYLE);
|
||||
else
|
||||
/* If no window, return sizes for a default window with title bar and border */
|
||||
windowStyle = WS_OVERLAPPEDWINDOW;
|
||||
|
||||
switch( eWhat )
|
||||
{
|
||||
case GLUT_WINDOW_BORDER_WIDTH:
|
||||
{
|
||||
int xBorderWidth, yBorderWidth;
|
||||
fghGetBorderWidth(windowStyle, &xBorderWidth, &yBorderWidth);
|
||||
return xBorderWidth;
|
||||
}
|
||||
case GLUT_WINDOW_HEADER_HEIGHT:
|
||||
/* Need to query for WS_MAXIMIZEBOX to see if we have a title bar, the WS_CAPTION query is also true for a WS_DLGFRAME only... */
|
||||
return (windowStyle & WS_MAXIMIZEBOX)? GetSystemMetrics( SM_CYCAPTION ) : 0;
|
||||
}
|
||||
}
|
||||
#endif /* defined(_WIN32_WCE) */
|
||||
|
||||
case GLUT_DISPLAY_MODE_POSSIBLE:
|
||||
#if defined(_WIN32_WCE)
|
||||
return 0;
|
||||
#else
|
||||
return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,
|
||||
PFD_MAIN_PLANE );
|
||||
#endif /* defined(_WIN32_WCE) */
|
||||
|
||||
|
||||
case GLUT_WINDOW_FORMAT_ID:
|
||||
#if !defined(_WIN32_WCE)
|
||||
if( fgStructure.CurrentWindow != NULL )
|
||||
return GetPixelFormat( fgStructure.CurrentWindow->Window.Device );
|
||||
#endif /* defined(_WIN32_WCE) */
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
|
||||
/* The window structure queries */
|
||||
case GLUT_WINDOW_PARENT:
|
||||
if( fgStructure.CurrentWindow == NULL ) return 0;
|
||||
if( fgStructure.CurrentWindow->Parent == NULL ) return 0;
|
||||
return fgStructure.CurrentWindow->Parent->ID;
|
||||
|
||||
case GLUT_WINDOW_NUM_CHILDREN:
|
||||
if( fgStructure.CurrentWindow == NULL )
|
||||
return 0;
|
||||
return fgListLength( &fgStructure.CurrentWindow->Children );
|
||||
|
||||
case GLUT_WINDOW_CURSOR:
|
||||
if( fgStructure.CurrentWindow == NULL )
|
||||
return 0;
|
||||
return fgStructure.CurrentWindow->State.Cursor;
|
||||
|
||||
case GLUT_MENU_NUM_ITEMS:
|
||||
if( fgStructure.CurrentMenu == NULL )
|
||||
return 0;
|
||||
return fgListLength( &fgStructure.CurrentMenu->Entries );
|
||||
|
||||
case GLUT_ACTION_ON_WINDOW_CLOSE:
|
||||
return fgState.ActionOnWindowClose;
|
||||
|
||||
case GLUT_VERSION :
|
||||
return VERSION_MAJOR * 10000 + VERSION_MINOR * 100 + VERSION_PATCH;
|
||||
|
||||
case GLUT_RENDERING_CONTEXT:
|
||||
return fgState.UseCurrentContext ? GLUT_USE_CURRENT_CONTEXT
|
||||
: GLUT_CREATE_NEW_CONTEXT;
|
||||
|
||||
case GLUT_DIRECT_RENDERING:
|
||||
return fgState.DirectContext;
|
||||
|
||||
case GLUT_FULL_SCREEN:
|
||||
return fgStructure.CurrentWindow->State.IsFullscreen;
|
||||
|
||||
case GLUT_AUX:
|
||||
return fgState.AuxiliaryBufferNumber;
|
||||
|
||||
case GLUT_MULTISAMPLE:
|
||||
return fgState.SampleNumber;
|
||||
|
||||
default:
|
||||
fgWarning( "glutGet(): missing enum handle %d", eWhat );
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns various device information.
|
||||
*/
|
||||
int FGAPIENTRY glutDeviceGet( GLenum eWhat )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutDeviceGet" );
|
||||
|
||||
/* XXX WARNING: we are mostly lying in this function. */
|
||||
switch( eWhat )
|
||||
{
|
||||
case GLUT_HAS_KEYBOARD:
|
||||
/*
|
||||
* Win32 is assumed a keyboard, and this cannot be queried,
|
||||
* except for WindowsCE.
|
||||
*
|
||||
* X11 has a core keyboard by definition, although it can
|
||||
* be present as a virtual/dummy keyboard. For now, there
|
||||
* is no reliable way to tell if a real keyboard is present.
|
||||
*/
|
||||
#if defined(_WIN32_CE)
|
||||
return ( GetKeyboardStatus() & KBDI_KEYBOARD_PRESENT ) ? 1 : 0;
|
||||
# if FREEGLUT_LIB_PRAGMAS
|
||||
# pragma comment (lib,"Kbdui.lib")
|
||||
# endif
|
||||
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
|
||||
/* X11 has a mouse by definition */
|
||||
case GLUT_HAS_MOUSE:
|
||||
return 1 ;
|
||||
|
||||
case GLUT_NUM_MOUSE_BUTTONS:
|
||||
/* We should be able to pass NULL when the last argument is zero,
|
||||
* but at least one X server has a bug where this causes a segfault.
|
||||
*
|
||||
* In XFree86/Xorg servers, a mouse wheel is seen as two buttons
|
||||
* rather than an Axis; "freeglut_main.c" expects this when
|
||||
* checking for a wheel event.
|
||||
*/
|
||||
{
|
||||
unsigned char map;
|
||||
int nbuttons = XGetPointerMapping(fgDisplay.Display, &map,0);
|
||||
return nbuttons;
|
||||
}
|
||||
|
||||
#elif TARGET_HOST_MS_WINDOWS
|
||||
|
||||
case GLUT_HAS_MOUSE:
|
||||
/*
|
||||
* MS Windows can be booted without a mouse.
|
||||
*/
|
||||
return GetSystemMetrics( SM_MOUSEPRESENT );
|
||||
|
||||
case GLUT_NUM_MOUSE_BUTTONS:
|
||||
# if defined(_WIN32_WCE)
|
||||
return 1;
|
||||
# else
|
||||
return GetSystemMetrics( SM_CMOUSEBUTTONS );
|
||||
# endif
|
||||
#endif
|
||||
|
||||
case GLUT_HAS_JOYSTICK:
|
||||
return fgJoystickDetect ();
|
||||
|
||||
case GLUT_OWNS_JOYSTICK:
|
||||
return fgState.JoysticksInitialised;
|
||||
|
||||
case GLUT_JOYSTICK_POLL_RATE:
|
||||
return fgStructure.CurrentWindow ? fgStructure.CurrentWindow->State.JoystickPollRate : 0;
|
||||
|
||||
/* XXX The following two are only for Joystick 0 but this is an improvement */
|
||||
case GLUT_JOYSTICK_BUTTONS:
|
||||
return glutJoystickGetNumButtons ( 0 );
|
||||
|
||||
case GLUT_JOYSTICK_AXES:
|
||||
return glutJoystickGetNumAxes ( 0 );
|
||||
|
||||
case GLUT_HAS_DIAL_AND_BUTTON_BOX:
|
||||
return fgInputDeviceDetect ();
|
||||
|
||||
case GLUT_NUM_DIALS:
|
||||
if ( fgState.InputDevsInitialised ) return 8;
|
||||
return 0;
|
||||
|
||||
case GLUT_NUM_BUTTON_BOX_BUTTONS:
|
||||
return 0;
|
||||
|
||||
case GLUT_HAS_SPACEBALL:
|
||||
return fgHasSpaceball();
|
||||
|
||||
case GLUT_HAS_TABLET:
|
||||
return 0;
|
||||
|
||||
case GLUT_NUM_SPACEBALL_BUTTONS:
|
||||
return fgSpaceballNumButtons();
|
||||
|
||||
case GLUT_NUM_TABLET_BUTTONS:
|
||||
return 0;
|
||||
|
||||
case GLUT_DEVICE_IGNORE_KEY_REPEAT:
|
||||
return fgStructure.CurrentWindow ? fgStructure.CurrentWindow->State.IgnoreKeyRepeat : 0;
|
||||
|
||||
case GLUT_DEVICE_KEY_REPEAT:
|
||||
return fgState.KeyRepeat;
|
||||
|
||||
default:
|
||||
fgWarning( "glutDeviceGet(): missing enum handle %d", eWhat );
|
||||
break;
|
||||
}
|
||||
|
||||
/* And now -- the failure. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This should return the current state of ALT, SHIFT and CTRL keys.
|
||||
*/
|
||||
int FGAPIENTRY glutGetModifiers( void )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutGetModifiers" );
|
||||
if( fgState.Modifiers == INVALID_MODIFIERS )
|
||||
{
|
||||
fgWarning( "glutGetModifiers() called outside an input callback" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return fgState.Modifiers;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the state of the GLUT API overlay subsystem. A misery ;-)
|
||||
*/
|
||||
int FGAPIENTRY glutLayerGet( GLenum eWhat )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutLayerGet" );
|
||||
|
||||
/*
|
||||
* This is easy as layers are not implemented ;-)
|
||||
*
|
||||
* XXX Can we merge the UNIX/X11 and WIN32 sections? Or
|
||||
* XXX is overlay support planned?
|
||||
*/
|
||||
switch( eWhat )
|
||||
{
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
|
||||
case GLUT_OVERLAY_POSSIBLE:
|
||||
return 0;
|
||||
|
||||
case GLUT_LAYER_IN_USE:
|
||||
return GLUT_NORMAL;
|
||||
|
||||
case GLUT_HAS_OVERLAY:
|
||||
return 0;
|
||||
|
||||
case GLUT_TRANSPARENT_INDEX:
|
||||
/*
|
||||
* Return just anything, which is always defined as zero
|
||||
*
|
||||
* XXX HUH?
|
||||
*/
|
||||
return 0;
|
||||
|
||||
case GLUT_NORMAL_DAMAGED:
|
||||
/* XXX Actually I do not know. Maybe. */
|
||||
return 0;
|
||||
|
||||
case GLUT_OVERLAY_DAMAGED:
|
||||
return -1;
|
||||
|
||||
#elif TARGET_HOST_MS_WINDOWS
|
||||
|
||||
case GLUT_OVERLAY_POSSIBLE:
|
||||
/* return fgSetupPixelFormat( fgStructure.CurrentWindow, GL_TRUE,
|
||||
PFD_OVERLAY_PLANE ); */
|
||||
return 0 ;
|
||||
|
||||
case GLUT_LAYER_IN_USE:
|
||||
return GLUT_NORMAL;
|
||||
|
||||
case GLUT_HAS_OVERLAY:
|
||||
return 0;
|
||||
|
||||
case GLUT_TRANSPARENT_INDEX:
|
||||
/*
|
||||
* Return just anything, which is always defined as zero
|
||||
*
|
||||
* XXX HUH?
|
||||
*/
|
||||
return 0;
|
||||
|
||||
case GLUT_NORMAL_DAMAGED:
|
||||
/* XXX Actually I do not know. Maybe. */
|
||||
return 0;
|
||||
|
||||
case GLUT_OVERLAY_DAMAGED:
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
default:
|
||||
fgWarning( "glutLayerGet(): missing enum handle %d", eWhat );
|
||||
break;
|
||||
}
|
||||
|
||||
/* And fail. That's good. Programs do love failing. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int * FGAPIENTRY glutGetModeValues(GLenum eWhat, int * size)
|
||||
{
|
||||
int * array;
|
||||
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
int attributes[9];
|
||||
GLXFBConfig * fbconfigArray; /* Array of FBConfigs */
|
||||
int fbconfigArraySize; /* Number of FBConfigs in the array */
|
||||
int attribute_name = 0;
|
||||
#endif
|
||||
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED("glutGetModeValues");
|
||||
|
||||
array = NULL;
|
||||
*size = 0;
|
||||
|
||||
switch (eWhat)
|
||||
{
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
case GLUT_AUX:
|
||||
case GLUT_MULTISAMPLE:
|
||||
|
||||
attributes[0] = GLX_BUFFER_SIZE;
|
||||
attributes[1] = GLX_DONT_CARE;
|
||||
|
||||
switch (eWhat)
|
||||
{
|
||||
case GLUT_AUX:
|
||||
/*
|
||||
FBConfigs are now sorted by increasing number of auxiliary
|
||||
buffers. We want at least one buffer.
|
||||
*/
|
||||
attributes[2] = GLX_AUX_BUFFERS;
|
||||
attributes[3] = 1;
|
||||
attributes[4] = None;
|
||||
|
||||
attribute_name = GLX_AUX_BUFFERS;
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case GLUT_MULTISAMPLE:
|
||||
attributes[2] = GLX_AUX_BUFFERS;
|
||||
attributes[3] = GLX_DONT_CARE;
|
||||
attributes[4] = GLX_SAMPLE_BUFFERS;
|
||||
attributes[5] = 1;
|
||||
/*
|
||||
FBConfigs are now sorted by increasing number of samples per
|
||||
pixel. We want at least one sample.
|
||||
*/
|
||||
attributes[6] = GLX_SAMPLES;
|
||||
attributes[7] = 1;
|
||||
attributes[8] = None;
|
||||
|
||||
attribute_name = GLX_SAMPLES;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
fbconfigArray = glXChooseFBConfig(fgDisplay.Display,
|
||||
fgDisplay.Screen,
|
||||
attributes,
|
||||
&fbconfigArraySize);
|
||||
|
||||
if (fbconfigArray != NULL)
|
||||
{
|
||||
int * temp_array;
|
||||
int result; /* Returned by glXGetFBConfigAttrib. Not checked. */
|
||||
int previous_value;
|
||||
int i;
|
||||
|
||||
temp_array = malloc(sizeof(int) * fbconfigArraySize);
|
||||
previous_value = 0;
|
||||
|
||||
for (i = 0; i < fbconfigArraySize; i++)
|
||||
{
|
||||
int value;
|
||||
|
||||
result = glXGetFBConfigAttrib(fgDisplay.Display,
|
||||
fbconfigArray[i],
|
||||
attribute_name,
|
||||
&value);
|
||||
if (value > previous_value)
|
||||
{
|
||||
temp_array[*size] = value;
|
||||
previous_value = value;
|
||||
(*size)++;
|
||||
}
|
||||
}
|
||||
|
||||
array = malloc(sizeof(int) * (*size));
|
||||
for (i = 0; i < *size; i++)
|
||||
{
|
||||
array[i] = temp_array[i];
|
||||
}
|
||||
|
||||
free(temp_array);
|
||||
XFree(fbconfigArray);
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
/*** END OF FILE ***/
|
2849
examples/opengl-framework/freeglut/freeglut_stroke_mono_roman.c
Normal file
2849
examples/opengl-framework/freeglut/freeglut_stroke_mono_roman.c
Normal file
File diff suppressed because it is too large
Load Diff
2849
examples/opengl-framework/freeglut/freeglut_stroke_roman.c
Normal file
2849
examples/opengl-framework/freeglut/freeglut_stroke_roman.c
Normal file
File diff suppressed because it is too large
Load Diff
598
examples/opengl-framework/freeglut/freeglut_structure.c
Normal file
598
examples/opengl-framework/freeglut/freeglut_structure.c
Normal file
|
@ -0,0 +1,598 @@
|
|||
/*
|
||||
* freeglut_structure.c
|
||||
*
|
||||
* Windows and menus need tree structure
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Sat Dec 18 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.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
/* -- GLOBAL EXPORTS ------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The SFG_Structure container holds information about windows and menus
|
||||
* created between glutInit() and glutMainLoop() return.
|
||||
*/
|
||||
|
||||
SFG_Structure fgStructure = { { NULL, NULL }, /* The list of windows */
|
||||
{ NULL, NULL }, /* The list of menus */
|
||||
{ NULL, NULL }, /* Windows to Destroy list */
|
||||
NULL, /* The current window */
|
||||
NULL, /* The current menu */
|
||||
NULL, /* The menu OpenGL context */
|
||||
NULL, /* The game mode window */
|
||||
0, /* The current new window ID */
|
||||
0 }; /* The current new menu ID */
|
||||
|
||||
|
||||
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
static void fghClearCallBacks( SFG_Window *window )
|
||||
{
|
||||
if( window )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < TOTAL_CALLBACKS; ++i )
|
||||
window->CallBacks[ i ] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This private function creates, opens and adds to the hierarchy
|
||||
* a freeglut window complete with OpenGL context and stuff...
|
||||
*
|
||||
* If parent is set to NULL, the window created will be a topmost one.
|
||||
*/
|
||||
SFG_Window* fgCreateWindow( SFG_Window* parent, const char* title,
|
||||
GLboolean positionUse, int x, int y,
|
||||
GLboolean sizeUse, int w, int h,
|
||||
GLboolean gameMode, GLboolean isMenu )
|
||||
{
|
||||
/* Have the window object created */
|
||||
SFG_Window *window = (SFG_Window *)calloc( sizeof(SFG_Window), 1 );
|
||||
|
||||
#if TARGET_HOST_UNIX_X11
|
||||
window->Window.FBConfig = NULL;
|
||||
#endif
|
||||
fghClearCallBacks( window );
|
||||
|
||||
/* Initialize the object properties */
|
||||
window->ID = ++fgStructure.WindowID;
|
||||
#if TARGET_HOST_POSIX_X11
|
||||
window->State.OldHeight = window->State.OldWidth = -1;
|
||||
#endif
|
||||
|
||||
fgListInit( &window->Children );
|
||||
if( parent )
|
||||
{
|
||||
fgListAppend( &parent->Children, &window->Node );
|
||||
window->Parent = parent;
|
||||
}
|
||||
else
|
||||
fgListAppend( &fgStructure.Windows, &window->Node );
|
||||
|
||||
/* Set the default mouse cursor and reset the modifiers value */
|
||||
window->State.Cursor = GLUT_CURSOR_INHERIT;
|
||||
|
||||
window->IsMenu = isMenu;
|
||||
|
||||
window->State.IgnoreKeyRepeat = GL_FALSE;
|
||||
window->State.KeyRepeating = GL_FALSE;
|
||||
window->State.IsFullscreen = GL_FALSE;
|
||||
|
||||
/*
|
||||
* Open the window now. The fgOpenWindow() function is system
|
||||
* dependant, and resides in freeglut_window.c. Uses fgState.
|
||||
*/
|
||||
fgOpenWindow( window, title, positionUse, x, y, sizeUse, w, h, gameMode,
|
||||
(GLboolean)(parent ? GL_TRUE : GL_FALSE) );
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/*
|
||||
* This private function creates a menu and adds it to the menus list
|
||||
*/
|
||||
SFG_Menu* fgCreateMenu( FGCBMenu menuCallback )
|
||||
{
|
||||
int x = 100, y = 100, w = 1, h = 1;
|
||||
SFG_Window *current_window = fgStructure.CurrentWindow;
|
||||
|
||||
/* Have the menu object created */
|
||||
SFG_Menu* menu = (SFG_Menu *)calloc( sizeof(SFG_Menu), 1 );
|
||||
|
||||
menu->ParentWindow = NULL;
|
||||
|
||||
/* Create a window for the menu to reside in. */
|
||||
|
||||
fgCreateWindow( NULL, "freeglut menu", GL_TRUE, x, y, GL_TRUE, w, h,
|
||||
GL_FALSE, GL_TRUE );
|
||||
menu->Window = fgStructure.CurrentWindow;
|
||||
glutDisplayFunc( fgDisplayMenu );
|
||||
|
||||
glutHideWindow( ); /* Hide the window for now */
|
||||
fgSetWindow( current_window );
|
||||
|
||||
/* Initialize the object properties: */
|
||||
menu->ID = ++fgStructure.MenuID;
|
||||
menu->Callback = menuCallback;
|
||||
menu->ActiveEntry = NULL;
|
||||
|
||||
fgListInit( &menu->Entries );
|
||||
fgListAppend( &fgStructure.Menus, &menu->Node );
|
||||
|
||||
/* Newly created menus implicitly become current ones */
|
||||
fgStructure.CurrentMenu = menu;
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to add a window to the linked list of windows to destroy.
|
||||
* Subwindows are automatically added because they hang from the window
|
||||
* structure.
|
||||
*/
|
||||
void fgAddToWindowDestroyList( SFG_Window* window )
|
||||
{
|
||||
SFG_WindowList *new_list_entry =
|
||||
( SFG_WindowList* )malloc( sizeof(SFG_WindowList ) );
|
||||
new_list_entry->window = window;
|
||||
fgListAppend( &fgStructure.WindowsToDestroy, &new_list_entry->node );
|
||||
|
||||
/* Check if the window is the current one... */
|
||||
if( fgStructure.CurrentWindow == window )
|
||||
fgStructure.CurrentWindow = NULL;
|
||||
|
||||
/*
|
||||
* Clear all window callbacks except Destroy, which will
|
||||
* be invoked later. Right now, we are potentially carrying
|
||||
* out a freeglut operation at the behest of a client callback,
|
||||
* so we are reluctant to re-enter the client with the Destroy
|
||||
* callback, right now. The others are all wiped out, however,
|
||||
* to ensure that they are no longer called after this point.
|
||||
*/
|
||||
{
|
||||
FGCBDestroy destroy = (FGCBDestroy)FETCH_WCB( *window, Destroy );
|
||||
fghClearCallBacks( window );
|
||||
SET_WCB( *window, Destroy, destroy );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to close down all the windows in the "WindowsToDestroy" list
|
||||
*/
|
||||
void fgCloseWindows( )
|
||||
{
|
||||
while( fgStructure.WindowsToDestroy.First )
|
||||
{
|
||||
SFG_WindowList *window_ptr = fgStructure.WindowsToDestroy.First;
|
||||
fgDestroyWindow( window_ptr->window );
|
||||
fgListRemove( &fgStructure.WindowsToDestroy, &window_ptr->node );
|
||||
free( window_ptr );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function destroys a window and all of its subwindows. Actually,
|
||||
* another function, defined in freeglut_window.c is called, but this is
|
||||
* a whole different story...
|
||||
*/
|
||||
void fgDestroyWindow( SFG_Window* window )
|
||||
{
|
||||
FREEGLUT_INTERNAL_ERROR_EXIT ( window, "Window destroy function called with null window",
|
||||
"fgDestroyWindow" );
|
||||
|
||||
while( window->Children.First )
|
||||
fgDestroyWindow( ( SFG_Window * )window->Children.First );
|
||||
|
||||
{
|
||||
SFG_Window *activeWindow = fgStructure.CurrentWindow;
|
||||
INVOKE_WCB( *window, Destroy, ( ) );
|
||||
fgSetWindow( activeWindow );
|
||||
}
|
||||
|
||||
if( window->Parent )
|
||||
fgListRemove( &window->Parent->Children, &window->Node );
|
||||
else
|
||||
fgListRemove( &fgStructure.Windows, &window->Node );
|
||||
|
||||
if( window->ActiveMenu )
|
||||
fgDeactivateMenu( window );
|
||||
|
||||
fghClearCallBacks( window );
|
||||
fgCloseWindow( window );
|
||||
free( window );
|
||||
if( fgStructure.CurrentWindow == window )
|
||||
fgStructure.CurrentWindow = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a helper static function that removes a menu (given its pointer)
|
||||
* from any windows that can be accessed from a given parent...
|
||||
*/
|
||||
static void fghRemoveMenuFromWindow( SFG_Window* window, SFG_Menu* menu )
|
||||
{
|
||||
SFG_Window *subWindow;
|
||||
int i;
|
||||
|
||||
/* Check whether this is the active menu in the window */
|
||||
if ( menu == window->ActiveMenu )
|
||||
window->ActiveMenu = NULL ;
|
||||
|
||||
/*
|
||||
* Check if the menu is attached to the current window,
|
||||
* if so, have it detached (by overwriting with a NULL):
|
||||
*/
|
||||
for( i = 0; i < FREEGLUT_MAX_MENUS; i++ )
|
||||
if( window->Menu[ i ] == menu )
|
||||
window->Menu[ i ] = NULL;
|
||||
|
||||
/* Call this function for all of the window's children recursively: */
|
||||
for( subWindow = (SFG_Window *)window->Children.First;
|
||||
subWindow;
|
||||
subWindow = (SFG_Window *)subWindow->Node.Next)
|
||||
fghRemoveMenuFromWindow( subWindow, menu );
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a static helper function that removes menu references
|
||||
* from another menu, given two pointers to them...
|
||||
*/
|
||||
static void fghRemoveMenuFromMenu( SFG_Menu* from, SFG_Menu* menu )
|
||||
{
|
||||
SFG_MenuEntry *entry;
|
||||
|
||||
for( entry = (SFG_MenuEntry *)from->Entries.First;
|
||||
entry;
|
||||
entry = ( SFG_MenuEntry * )entry->Node.Next )
|
||||
if( entry->SubMenu == menu )
|
||||
entry->SubMenu = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function destroys a menu specified by the parameter. All menus
|
||||
* and windows are updated to make sure no ill pointers hang around.
|
||||
*/
|
||||
void fgDestroyMenu( SFG_Menu* menu )
|
||||
{
|
||||
SFG_Window *window;
|
||||
SFG_Menu *from;
|
||||
|
||||
FREEGLUT_INTERNAL_ERROR_EXIT ( menu, "Menu destroy function called with null menu",
|
||||
"fgDestroyMenu" );
|
||||
|
||||
/* First of all, have all references to this menu removed from all windows: */
|
||||
for( window = (SFG_Window *)fgStructure.Windows.First;
|
||||
window;
|
||||
window = (SFG_Window *)window->Node.Next )
|
||||
fghRemoveMenuFromWindow( window, menu );
|
||||
|
||||
/* Now proceed with removing menu entries that lead to this menu */
|
||||
for( from = ( SFG_Menu * )fgStructure.Menus.First;
|
||||
from;
|
||||
from = ( SFG_Menu * )from->Node.Next )
|
||||
fghRemoveMenuFromMenu( from, menu );
|
||||
|
||||
/*
|
||||
* If the programmer defined a destroy callback, call it
|
||||
* A. Donev: But first make this the active menu
|
||||
*/
|
||||
if( menu->Destroy )
|
||||
{
|
||||
SFG_Menu *activeMenu=fgStructure.CurrentMenu;
|
||||
fgStructure.CurrentMenu = menu;
|
||||
menu->Destroy( );
|
||||
fgStructure.CurrentMenu = activeMenu;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we are pretty sure the menu is not used anywhere
|
||||
* and that we can remove all of its entries
|
||||
*/
|
||||
while( menu->Entries.First )
|
||||
{
|
||||
SFG_MenuEntry *entry = ( SFG_MenuEntry * ) menu->Entries.First;
|
||||
|
||||
fgListRemove( &menu->Entries, &entry->Node );
|
||||
|
||||
if( entry->Text )
|
||||
free( entry->Text );
|
||||
entry->Text = NULL;
|
||||
|
||||
free( entry );
|
||||
}
|
||||
|
||||
if( fgStructure.CurrentWindow == menu->Window )
|
||||
fgSetWindow( NULL );
|
||||
fgDestroyWindow( menu->Window );
|
||||
fgListRemove( &fgStructure.Menus, &menu->Node );
|
||||
if( fgStructure.CurrentMenu == menu )
|
||||
fgStructure.CurrentMenu = NULL;
|
||||
|
||||
free( menu );
|
||||
}
|
||||
|
||||
/*
|
||||
* This function should be called on glutInit(). It will prepare the internal
|
||||
* structure of freeglut to be used in the application. The structure will be
|
||||
* destroyed using fgDestroyStructure() on glutMainLoop() return. In that
|
||||
* case further use of freeglut should be preceeded with a glutInit() call.
|
||||
*/
|
||||
void fgCreateStructure( void )
|
||||
{
|
||||
/*
|
||||
* We will be needing two lists: the first containing windows,
|
||||
* and the second containing the user-defined menus.
|
||||
* Also, no current window/menu is set, as none has been created yet.
|
||||
*/
|
||||
|
||||
fgListInit(&fgStructure.Windows);
|
||||
fgListInit(&fgStructure.Menus);
|
||||
fgListInit(&fgStructure.WindowsToDestroy);
|
||||
|
||||
fgStructure.CurrentWindow = NULL;
|
||||
fgStructure.CurrentMenu = NULL;
|
||||
fgStructure.MenuContext = NULL;
|
||||
fgStructure.GameModeWindow = NULL;
|
||||
fgStructure.WindowID = 0;
|
||||
fgStructure.MenuID = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is automatically called on glutMainLoop() return.
|
||||
* It should deallocate and destroy all remnants of previous
|
||||
* glutInit()-enforced structure initialization...
|
||||
*/
|
||||
void fgDestroyStructure( void )
|
||||
{
|
||||
/* Clean up the WindowsToDestroy list. */
|
||||
fgCloseWindows( );
|
||||
|
||||
/* Make sure all windows and menus have been deallocated */
|
||||
while( fgStructure.Menus.First )
|
||||
fgDestroyMenu( ( SFG_Menu * )fgStructure.Menus.First );
|
||||
|
||||
while( fgStructure.Windows.First )
|
||||
fgDestroyWindow( ( SFG_Window * )fgStructure.Windows.First );
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to enumerate through all registered top-level windows
|
||||
*/
|
||||
void fgEnumWindows( FGCBenumerator enumCallback, SFG_Enumerator* enumerator )
|
||||
{
|
||||
SFG_Window *window;
|
||||
|
||||
FREEGLUT_INTERNAL_ERROR_EXIT ( enumCallback && enumerator,
|
||||
"Enumerator or callback missing from window enumerator call",
|
||||
"fgEnumWindows" );
|
||||
|
||||
/* Check every of the top-level windows */
|
||||
for( window = ( SFG_Window * )fgStructure.Windows.First;
|
||||
window;
|
||||
window = ( SFG_Window * )window->Node.Next )
|
||||
{
|
||||
enumCallback( window, enumerator );
|
||||
if( enumerator->found )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to enumerate through all a window's subwindows
|
||||
* (single level descent)
|
||||
*/
|
||||
void fgEnumSubWindows( SFG_Window* window, FGCBenumerator enumCallback,
|
||||
SFG_Enumerator* enumerator )
|
||||
{
|
||||
SFG_Window *child;
|
||||
|
||||
FREEGLUT_INTERNAL_ERROR_EXIT ( enumCallback && enumerator,
|
||||
"Enumerator or callback missing from subwindow enumerator call",
|
||||
"fgEnumSubWindows" );
|
||||
FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Window Enumeration" );
|
||||
|
||||
for( child = ( SFG_Window * )window->Children.First;
|
||||
child;
|
||||
child = ( SFG_Window * )child->Node.Next )
|
||||
{
|
||||
enumCallback( child, enumerator );
|
||||
if( enumerator->found )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A static helper function to look for a window given its handle
|
||||
*/
|
||||
static void fghcbWindowByHandle( SFG_Window *window,
|
||||
SFG_Enumerator *enumerator )
|
||||
{
|
||||
if ( enumerator->found )
|
||||
return;
|
||||
|
||||
/* Check the window's handle. Hope this works. Looks ugly. That's for sure. */
|
||||
if( window->Window.Handle == (SFG_WindowHandleType) (enumerator->data) )
|
||||
{
|
||||
enumerator->found = GL_TRUE;
|
||||
enumerator->data = window;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise, check this window's children */
|
||||
fgEnumSubWindows( window, fghcbWindowByHandle, enumerator );
|
||||
}
|
||||
|
||||
/*
|
||||
* fgWindowByHandle returns a (SFG_Window *) value pointing to the
|
||||
* first window in the queue matching the specified window handle.
|
||||
* The function is defined in freeglut_structure.c file.
|
||||
*/
|
||||
SFG_Window* fgWindowByHandle ( SFG_WindowHandleType hWindow )
|
||||
{
|
||||
SFG_Enumerator enumerator;
|
||||
|
||||
/* This is easy and makes use of the windows enumeration defined above */
|
||||
enumerator.found = GL_FALSE;
|
||||
enumerator.data = (void *)hWindow;
|
||||
fgEnumWindows( fghcbWindowByHandle, &enumerator );
|
||||
|
||||
if( enumerator.found )
|
||||
return( SFG_Window *) enumerator.data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* A static helper function to look for a window given its ID
|
||||
*/
|
||||
static void fghcbWindowByID( SFG_Window *window, SFG_Enumerator *enumerator )
|
||||
{
|
||||
/* Make sure we do not overwrite our precious results... */
|
||||
if( enumerator->found )
|
||||
return;
|
||||
|
||||
/* Check the window's handle. Hope this works. Looks ugly. That's for sure. */
|
||||
if( window->ID == *( int *)(enumerator->data) )
|
||||
{
|
||||
enumerator->found = GL_TRUE;
|
||||
enumerator->data = window;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise, check this window's children */
|
||||
fgEnumSubWindows( window, fghcbWindowByID, enumerator );
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is similiar to the previous one, except it is
|
||||
* looking for a specified (sub)window identifier. The function
|
||||
* is defined in freeglut_structure.c file.
|
||||
*/
|
||||
SFG_Window* fgWindowByID( int windowID )
|
||||
{
|
||||
SFG_Enumerator enumerator;
|
||||
|
||||
/* Uses a method very similiar for fgWindowByHandle... */
|
||||
enumerator.found = GL_FALSE;
|
||||
enumerator.data = ( void * )&windowID;
|
||||
fgEnumWindows( fghcbWindowByID, &enumerator );
|
||||
if( enumerator.found )
|
||||
return ( SFG_Window * )enumerator.data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Looks up a menu given its ID. This is easier that fgWindowByXXX
|
||||
* as all menus are placed in one doubly linked list...
|
||||
*/
|
||||
SFG_Menu* fgMenuByID( int menuID )
|
||||
{
|
||||
SFG_Menu *menu = NULL;
|
||||
|
||||
/* It's enough to check all entries in fgStructure.Menus... */
|
||||
for( menu = (SFG_Menu *)fgStructure.Menus.First;
|
||||
menu;
|
||||
menu = (SFG_Menu *)menu->Node.Next )
|
||||
if( menu->ID == menuID )
|
||||
return menu;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* List functions...
|
||||
*/
|
||||
void fgListInit(SFG_List *list)
|
||||
{
|
||||
list->First = NULL;
|
||||
list->Last = NULL;
|
||||
}
|
||||
|
||||
void fgListAppend(SFG_List *list, SFG_Node *node)
|
||||
{
|
||||
if ( list->Last )
|
||||
{
|
||||
SFG_Node *ln = (SFG_Node *) list->Last;
|
||||
ln->Next = node;
|
||||
node->Prev = ln;
|
||||
}
|
||||
else
|
||||
{
|
||||
node->Prev = NULL;
|
||||
list->First = node;
|
||||
}
|
||||
|
||||
node->Next = NULL;
|
||||
list->Last = node;
|
||||
}
|
||||
|
||||
void fgListRemove(SFG_List *list, SFG_Node *node)
|
||||
{
|
||||
if( node->Next )
|
||||
( ( SFG_Node * )node->Next )->Prev = node->Prev;
|
||||
if( node->Prev )
|
||||
( ( SFG_Node * )node->Prev )->Next = node->Next;
|
||||
if( ( ( SFG_Node * )list->First ) == node )
|
||||
list->First = node->Next;
|
||||
if( ( ( SFG_Node * )list->Last ) == node )
|
||||
list->Last = node->Prev;
|
||||
}
|
||||
|
||||
int fgListLength(SFG_List *list)
|
||||
{
|
||||
SFG_Node *node;
|
||||
int length = 0;
|
||||
|
||||
for( node =( SFG_Node * )list->First;
|
||||
node;
|
||||
node = ( SFG_Node * )node->Next )
|
||||
++length;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
void fgListInsert(SFG_List *list, SFG_Node *next, SFG_Node *node)
|
||||
{
|
||||
SFG_Node *prev;
|
||||
|
||||
if( (node->Next = next) )
|
||||
{
|
||||
prev = next->Prev;
|
||||
next->Prev = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = list->Last;
|
||||
list->Last = node;
|
||||
}
|
||||
|
||||
if( (node->Prev = prev) )
|
||||
prev->Next = node;
|
||||
else
|
||||
list->First = node;
|
||||
}
|
||||
|
||||
/*** END OF FILE ***/
|
200
examples/opengl-framework/freeglut/freeglut_teapot.c
Normal file
200
examples/opengl-framework/freeglut/freeglut_teapot.c
Normal file
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* freeglut_teapot.c
|
||||
*
|
||||
* Teapot(tm) rendering code.
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Fri Dec 24 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Original teapot code copyright follows:
|
||||
*/
|
||||
|
||||
/*
|
||||
* (c) Copyright 1993, Silicon Graphics, Inc.
|
||||
*
|
||||
* ALL RIGHTS RESERVED
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software
|
||||
* for any purpose and without fee is hereby granted, provided
|
||||
* that the above copyright notice appear in all copies and that
|
||||
* both the copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of Silicon
|
||||
* Graphics, Inc. not be used in advertising or publicity
|
||||
* pertaining to distribution of the software without specific,
|
||||
* written prior permission.
|
||||
*
|
||||
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU
|
||||
* "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR
|
||||
* OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO
|
||||
* EVENT SHALL SILICON GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE
|
||||
* ELSE FOR ANY DIRECT, SPECIAL, INCIDENTAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER,
|
||||
* INCLUDING WITHOUT LIMITATION, LOSS OF PROFIT, LOSS OF USE,
|
||||
* SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD PARTIES, WHETHER OR
|
||||
* NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* US Government Users Restricted Rights
|
||||
*
|
||||
* Use, duplication, or disclosure by the Government is subject to
|
||||
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
|
||||
* (c)(1)(ii) of the Rights in Technical Data and Computer
|
||||
* Software clause at DFARS 252.227-7013 and/or in similar or
|
||||
* successor clauses in the FAR or the DOD or NASA FAR
|
||||
* Supplement. Unpublished-- rights reserved under the copyright
|
||||
* laws of the United States. Contractor/manufacturer is Silicon
|
||||
* Graphics, Inc., 2011 N. Shoreline Blvd., Mountain View, CA
|
||||
* 94039-7311.
|
||||
*
|
||||
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
#include "freeglut_teapot_data.h"
|
||||
|
||||
/* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
|
||||
|
||||
|
||||
static void fghTeapot( GLint grid, GLdouble scale, GLenum type )
|
||||
{
|
||||
#if defined(_WIN32_WCE)
|
||||
int i, numV=sizeof(strip_vertices)/4, numI=sizeof(strip_normals)/4;
|
||||
#else
|
||||
double p[4][4][3], q[4][4][3], r[4][4][3], s[4][4][3];
|
||||
long i, j, k, l;
|
||||
#endif
|
||||
|
||||
glPushAttrib( GL_ENABLE_BIT | GL_EVAL_BIT );
|
||||
glEnable( GL_AUTO_NORMAL );
|
||||
glEnable( GL_NORMALIZE );
|
||||
glEnable( GL_MAP2_VERTEX_3 );
|
||||
glEnable( GL_MAP2_TEXTURE_COORD_2 );
|
||||
|
||||
glPushMatrix();
|
||||
glRotated( 270.0, 1.0, 0.0, 0.0 );
|
||||
glScaled( 0.5 * scale, 0.5 * scale, 0.5 * scale );
|
||||
glTranslated( 0.0, 0.0, -1.5 );
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
glRotated( 90.0, 1.0, 0.0, 0.0 );
|
||||
glBegin( GL_TRIANGLE_STRIP );
|
||||
|
||||
for( i = 0; i < numV-1; i++ )
|
||||
{
|
||||
int vidx = strip_vertices[i],
|
||||
nidx = strip_normals[i];
|
||||
|
||||
if( vidx != -1 )
|
||||
{
|
||||
glNormal3fv( normals[nidx] );
|
||||
glVertex3fv( vertices[vidx] );
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnd();
|
||||
glBegin( GL_TRIANGLE_STRIP );
|
||||
}
|
||||
}
|
||||
|
||||
glEnd();
|
||||
#else
|
||||
for (i = 0; i < 10; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
for (l = 0; l < 3; l++) {
|
||||
p[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
|
||||
q[j][k][l] = cpdata[patchdata[i][j * 4 + (3 - k)]][l];
|
||||
if (l == 1)
|
||||
q[j][k][l] *= -1.0;
|
||||
if (i < 6) {
|
||||
r[j][k][l] =
|
||||
cpdata[patchdata[i][j * 4 + (3 - k)]][l];
|
||||
if (l == 0)
|
||||
r[j][k][l] *= -1.0;
|
||||
s[j][k][l] = cpdata[patchdata[i][j * 4 + k]][l];
|
||||
if (l == 0)
|
||||
s[j][k][l] *= -1.0;
|
||||
if (l == 1)
|
||||
s[j][k][l] *= -1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glMap2d(GL_MAP2_TEXTURE_COORD_2, 0.0, 1.0, 2, 2, 0.0, 1.0, 4, 2,
|
||||
&tex[0][0][0]);
|
||||
glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4,
|
||||
&p[0][0][0]);
|
||||
glMapGrid2d(grid, 0.0, 1.0, grid, 0.0, 1.0);
|
||||
glEvalMesh2(type, 0, grid, 0, grid);
|
||||
glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4,
|
||||
&q[0][0][0]);
|
||||
glEvalMesh2(type, 0, grid, 0, grid);
|
||||
if (i < 6) {
|
||||
glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4,
|
||||
&r[0][0][0]);
|
||||
glEvalMesh2(type, 0, grid, 0, grid);
|
||||
glMap2d(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4,
|
||||
&s[0][0][0]);
|
||||
glEvalMesh2(type, 0, grid, 0, grid);
|
||||
}
|
||||
}
|
||||
#endif /* defined(_WIN32_WCE) */
|
||||
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Renders a beautiful wired teapot...
|
||||
*/
|
||||
void FGAPIENTRY glutWireTeapot( GLdouble size )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutWireTeapot" );
|
||||
/* We will use the general teapot rendering code */
|
||||
fghTeapot( 10, size, GL_LINE );
|
||||
}
|
||||
|
||||
/*
|
||||
* Renders a beautiful filled teapot...
|
||||
*/
|
||||
void FGAPIENTRY glutSolidTeapot( GLdouble size )
|
||||
{
|
||||
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutSolidTeapot" );
|
||||
/* We will use the general teapot rendering code */
|
||||
fghTeapot( 7, size, GL_FILL );
|
||||
}
|
||||
|
||||
/*** END OF FILE ***/
|
||||
|
||||
|
||||
|
||||
|
||||
|
2429
examples/opengl-framework/freeglut/freeglut_teapot_data.h
Normal file
2429
examples/opengl-framework/freeglut/freeglut_teapot_data.h
Normal file
File diff suppressed because it is too large
Load Diff
50
examples/opengl-framework/freeglut/freeglut_videoresize.c
Normal file
50
examples/opengl-framework/freeglut/freeglut_videoresize.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* freeglut_videoresize.c
|
||||
*
|
||||
* Video resize functions (as defined by GLUT API)
|
||||
*
|
||||
* Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
|
||||
* Written by Pawel W. Olszta, <olszta@sourceforge.net>
|
||||
* Creation date: Thu Dec 16 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.
|
||||
*/
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
/*
|
||||
* NOTE: functions declared in this file probably will not be implemented.
|
||||
*/
|
||||
|
||||
/* -- INTERFACE FUNCTIONS -------------------------------------------------- */
|
||||
|
||||
int FGAPIENTRY glutVideoResizeGet( GLenum eWhat ) { return( 0x00 ); }
|
||||
void FGAPIENTRY glutSetupVideoResizing( void ) { /* Not implemented */ }
|
||||
void FGAPIENTRY glutStopVideoResizing( void ) { /* Not implemented */ }
|
||||
void FGAPIENTRY glutVideoResize( int x, int y, int w, int h ) { /* Not implemented */ }
|
||||
void FGAPIENTRY glutVideoPan( int x, int y, int w, int h ) { /* Not implemented */ }
|
||||
|
||||
/*** END OF FILE ***/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
2162
examples/opengl-framework/freeglut/freeglut_window.c
Normal file
2162
examples/opengl-framework/freeglut/freeglut_window.c
Normal file
File diff suppressed because it is too large
Load Diff
219
examples/opengl-framework/freeglut/freeglut_xinput.c
Normal file
219
examples/opengl-framework/freeglut/freeglut_xinput.c
Normal file
|
@ -0,0 +1,219 @@
|
|||
/* Written for XI1 by Nikolas Doerfler <doerflen@in.tum.de> (c) 2008 *
|
||||
* Rewritten for XI2 by Florian Echtler <echtler@in.tum.de> (c) 2009 */
|
||||
|
||||
#include <GL/freeglut.h>
|
||||
|
||||
#include "freeglut_internal.h"
|
||||
|
||||
#if TARGET_HOST_POSIX_X11 && HAVE_X11_EXTENSIONS_XINPUT2_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XInput2.h>
|
||||
|
||||
/* import function from freeglut_main.c */
|
||||
int fghGetXModifiers( int state );
|
||||
|
||||
/* extension opcode for XInput */
|
||||
int xi_opcode = -1;
|
||||
|
||||
/**
|
||||
* \brief Sets window up for XI2 events.
|
||||
*/
|
||||
void fgRegisterDevices( Display* dpy, Window* win ) {
|
||||
|
||||
XIEventMask mask;
|
||||
unsigned char flags[2] = { 0, 0 };
|
||||
int event, error;
|
||||
|
||||
/*Display* dpy = fgDisplay.Display;
|
||||
Window* win = glutGetXWindow();*/
|
||||
|
||||
/* get XInput extension opcode */
|
||||
if (!XQueryExtension( dpy, "XInputExtension", &xi_opcode, &event, &error )) { xi_opcode = -1; }
|
||||
|
||||
/* Select for motion events */
|
||||
mask.deviceid = XIAllMasterDevices;
|
||||
mask.mask_len = 2;
|
||||
mask.mask = flags;
|
||||
|
||||
XISetMask(mask.mask, XI_Enter);
|
||||
XISetMask(mask.mask, XI_Motion);
|
||||
XISetMask(mask.mask, XI_ButtonPress);
|
||||
XISetMask(mask.mask, XI_ButtonRelease);
|
||||
XISetMask(mask.mask, XI_Leave);
|
||||
/*XISetMask(mask.mask, XI_KeyPress);
|
||||
XISetMask(mask.mask, XI_KeyRelease);
|
||||
XISetMask(mask.mask, XI_DeviceChanged);
|
||||
XISetMask(mask.mask, XI_RawEvent);
|
||||
XISetMask(mask.mask, XI_FocusIn);
|
||||
XISetMask(mask.mask, XI_FocusOut);
|
||||
XISetMask(mask.mask, XI_HierarchyChanged);*/
|
||||
|
||||
XISelectEvents( dpy, *win, &mask, 1 );
|
||||
}
|
||||
|
||||
|
||||
void fgPrintXILeaveEvent(XILeaveEvent* event)
|
||||
{
|
||||
char* mode = "";
|
||||
char* detail = "";
|
||||
int i;
|
||||
|
||||
printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n",
|
||||
event->root, event->event, event->child);
|
||||
switch(event->mode)
|
||||
{
|
||||
case NotifyNormal: mode = "NotifyNormal"; break;
|
||||
case NotifyGrab: mode = "NotifyGrab"; break;
|
||||
case NotifyUngrab: mode = "NotifyUngrab"; break;
|
||||
case NotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break;
|
||||
}
|
||||
switch (event->detail)
|
||||
{
|
||||
case NotifyAncestor: detail = "NotifyAncestor"; break;
|
||||
case NotifyVirtual: detail = "NotifyVirtual"; break;
|
||||
case NotifyInferior: detail = "NotifyInferior"; break;
|
||||
case NotifyNonlinear: detail = "NotifyNonlinear"; break;
|
||||
case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break;
|
||||
case NotifyPointer: detail = "NotifyPointer"; break;
|
||||
case NotifyPointerRoot: detail = "NotifyPointerRoot"; break;
|
||||
case NotifyDetailNone: detail = "NotifyDetailNone"; break;
|
||||
}
|
||||
printf(" mode: %s (detail %s)\n", mode, detail);
|
||||
printf(" flags: %s %s\n", event->focus ? "[focus]" : "",
|
||||
event->same_screen ? "[same screen]" : "");
|
||||
printf(" buttons:");
|
||||
for (i = 0; i < event->buttons.mask_len * 8; i++)
|
||||
if (XIMaskIsSet(event->buttons.mask, i))
|
||||
printf(" %d", i);
|
||||
printf("\n");
|
||||
|
||||
printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n",
|
||||
event->mods.locked, event->mods.latched,
|
||||
event->mods.base);
|
||||
printf(" group: locked 0x%x latched 0x%x base 0x%x\n",
|
||||
event->group.locked, event->group.latched,
|
||||
event->group.base);
|
||||
|
||||
printf(" root x/y: %.2f / %.2f\n", event->root_x, event->root_y);
|
||||
printf(" event x/y: %.2f / %.2f\n", event->event_x, event->event_y);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void fgPrintXIDeviceEvent(XIDeviceEvent* event)
|
||||
{
|
||||
double *val;
|
||||
int i;
|
||||
|
||||
printf(" device: %d (%d)\n", event->deviceid, event->sourceid);
|
||||
printf(" detail: %d\n", event->detail);
|
||||
printf(" buttons:");
|
||||
for (i = 0; i < event->buttons.mask_len * 8; i++)
|
||||
if (XIMaskIsSet(event->buttons.mask, i))
|
||||
printf(" %d", i);
|
||||
printf("\n");
|
||||
|
||||
printf(" modifiers: locked 0x%x latched 0x%x base 0x%x\n",
|
||||
event->mods.locked, event->mods.latched,
|
||||
event->mods.base);
|
||||
printf(" group: locked 0x%x latched 0x%x base 0x%x\n",
|
||||
event->group.locked, event->group.latched,
|
||||
event->group.base);
|
||||
printf(" valuators:");
|
||||
|
||||
val = event->valuators.values;
|
||||
for (i = 0; i < event->valuators.mask_len * 8; i++)
|
||||
if (XIMaskIsSet(event->valuators.mask, i))
|
||||
printf(" %d: %.2f", i, *val++);
|
||||
printf("\n");
|
||||
|
||||
printf(" windows: root 0x%lx event 0x%lx child 0x%ld\n",
|
||||
event->root, event->event, event->child);
|
||||
printf(" root x/y: %.2f / %.2f\n", event->root_x, event->root_y);
|
||||
printf(" event x/y: %.2f / %.2f\n", event->event_x, event->event_y);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief This function is called when an Extension Event is received
|
||||
* and calls the corresponding callback functions for these events.
|
||||
*/
|
||||
void fgHandleExtensionEvents( XEvent* base_ev ) {
|
||||
|
||||
int i, button = 0;
|
||||
XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie);
|
||||
|
||||
if ( XGetEventData( fgDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) {
|
||||
|
||||
XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data);
|
||||
/*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/
|
||||
|
||||
SFG_Window* window = fgWindowByHandle( event->event );
|
||||
if (!window) return;
|
||||
|
||||
switch (cookie->evtype) {
|
||||
|
||||
case XI_Enter:
|
||||
case XI_Leave:
|
||||
fgState.Modifiers = fghGetXModifiers( ((XIEnterEvent*)event)->mods.base );
|
||||
INVOKE_WCB( *window, MultiEntry, (
|
||||
event->deviceid,
|
||||
(event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT)
|
||||
));
|
||||
#if _DEBUG
|
||||
fgPrintXILeaveEvent((XILeaveEvent*)event);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case XI_ButtonPress:
|
||||
case XI_ButtonRelease:
|
||||
fgState.Modifiers = fghGetXModifiers( event->mods.base );
|
||||
INVOKE_WCB( *window, MultiButton, (
|
||||
event->deviceid,
|
||||
event->event_x,
|
||||
event->event_y,
|
||||
(event->detail)-1,
|
||||
(event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP)
|
||||
));
|
||||
INVOKE_WCB( *window, Mouse, (
|
||||
(event->detail)-1,
|
||||
(event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP),
|
||||
event->event_x,
|
||||
event->event_y
|
||||
));
|
||||
break;
|
||||
|
||||
case XI_Motion:
|
||||
fgState.Modifiers = fghGetXModifiers( event->mods.base );
|
||||
for (i = 0; i < event->buttons.mask_len; i++) if (event->buttons.mask[i]) button = 1;
|
||||
if (button) {
|
||||
INVOKE_WCB( *window, MultiMotion, ( event->deviceid, event->event_x, event->event_y ) );
|
||||
INVOKE_WCB( *window, Motion, ( event->event_x, event->event_y ) );
|
||||
} else {
|
||||
INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) );
|
||||
INVOKE_WCB( *window, Passive, ( event->event_x, event->event_y ) );
|
||||
}
|
||||
#if _DEBUG
|
||||
fgPrintXIDeviceEvent(event);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
#if _DEBUG
|
||||
fgWarning( "Unknown XI2 device event:" );
|
||||
fgPrintXIDeviceEvent( event );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
fgState.Modifiers = INVALID_MODIFIERS;
|
||||
}
|
||||
XFreeEventData( fgDisplay.Display, cookie );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
21
examples/opengl-framework/freeglut/glut.h
Normal file
21
examples/opengl-framework/freeglut/glut.h
Normal 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__ */
|
97
examples/opengl-framework/src/Camera.cpp
Normal file
97
examples/opengl-framework/src/Camera.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
|
||||
// Libraries
|
||||
#include "Camera.h"
|
||||
#include "definitions.h"
|
||||
#include <cmath>
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Camera::Camera() : Object3D() {
|
||||
|
||||
// Set default values
|
||||
mFieldOfView = 45.0f;
|
||||
mSceneRadius = 1.0f;
|
||||
mNearPlane = 0.1f;
|
||||
mFarPlane = 10.0f;
|
||||
mWidth = 1;
|
||||
mHeight = 1;
|
||||
|
||||
// Update the projection matrix
|
||||
updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Camera::~Camera() {
|
||||
|
||||
}
|
||||
|
||||
// Update the projection matrix
|
||||
void Camera::updateProjectionMatrix() {
|
||||
|
||||
// Compute the aspect ratio
|
||||
float aspect = float(mWidth) / float(mHeight);
|
||||
|
||||
float top = mNearPlane * tan((mFieldOfView / 2.0f) * (float(PI) / 180.0f));
|
||||
float bottom = -top;
|
||||
float left = bottom * aspect;
|
||||
float right = top * aspect;
|
||||
|
||||
float fx = 2.0f * mNearPlane / (right - left);
|
||||
float fy = 2.0f * mNearPlane / (top - bottom);
|
||||
float fz = -(mFarPlane + mNearPlane) / (mFarPlane - mNearPlane);
|
||||
float fw = -2.0f * mFarPlane * mNearPlane / (mFarPlane - mNearPlane);
|
||||
|
||||
// Recompute the projection matrix
|
||||
mProjectionMatrix = Matrix4(fx, 0, 0, 0,
|
||||
0, fy, 0, 0,
|
||||
0, 0, fz, fw,
|
||||
0, 0, -1, 0);
|
||||
}
|
||||
|
||||
// Translate the camera go a given point using the dx, dy fraction
|
||||
void Camera::translateCamera(float dx, float dy, const Vector3& worldPoint) {
|
||||
|
||||
// Transform the world point into camera coordinates
|
||||
Vector3 pointCamera = mTransformMatrix.getInverse() * worldPoint;
|
||||
|
||||
// Get the depth
|
||||
float z = -pointCamera.z;
|
||||
|
||||
// Find the scaling of dx and dy from windows coordinates to near plane coordinates
|
||||
// and from there to camera coordinates at the object's depth
|
||||
float aspect = float(mWidth) / float(mHeight);
|
||||
float top = mNearPlane * tan(mFieldOfView * PI / 360.0f);
|
||||
float right = top * aspect;
|
||||
|
||||
// Translate the camera
|
||||
translateLocal(Vector3(2.0f * dx * right / mNearPlane * z,
|
||||
-2.0f * dy * top / mNearPlane * z,
|
||||
0.0f));
|
||||
}
|
181
examples/opengl-framework/src/Camera.h
Normal file
181
examples/opengl-framework/src/Camera.h
Normal file
|
@ -0,0 +1,181 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
// Libraries
|
||||
#include "Object3D.h"
|
||||
#include "definitions.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Camera
|
||||
class Camera : public Object3D {
|
||||
|
||||
protected :
|
||||
|
||||
// ------------------- Attributes ------------------- //
|
||||
|
||||
// Field of view
|
||||
float mFieldOfView;
|
||||
|
||||
// Radius of the scene
|
||||
float mSceneRadius;
|
||||
|
||||
// Near plane
|
||||
float mNearPlane;
|
||||
|
||||
// Far plane
|
||||
float mFarPlane;
|
||||
|
||||
// Width of the camera
|
||||
uint mWidth;
|
||||
|
||||
// Height of the camera
|
||||
uint mHeight;
|
||||
|
||||
// Projection matrix
|
||||
Matrix4 mProjectionMatrix;
|
||||
|
||||
// ------------------- Methods ------------------- //
|
||||
|
||||
// Update the projection matrix
|
||||
void updateProjectionMatrix();
|
||||
|
||||
public:
|
||||
|
||||
// ------------------- Methods ------------------- //
|
||||
|
||||
// Constructor
|
||||
Camera();
|
||||
|
||||
// Destructor
|
||||
~Camera();
|
||||
|
||||
// Get the projection matrix
|
||||
const Matrix4& getProjectionMatrix() const;
|
||||
|
||||
// Set the dimensions of the camera
|
||||
void setDimensions(uint width, uint height);
|
||||
|
||||
// Get the radius of the scene the camera should capture
|
||||
float getSceneRadius() const;
|
||||
|
||||
// Set the radius of the scene the camera should capture
|
||||
// This will update the clipping planes accordingly
|
||||
void setSceneRadius(float radius);
|
||||
|
||||
// Set the clipping planes
|
||||
void setClippingPlanes(float near, float far);
|
||||
|
||||
// Set the field of view
|
||||
void setFieldOfView(float fov);
|
||||
|
||||
// Set the zoom of the camera (a fraction between 0 and 1)
|
||||
void setZoom(float fraction);
|
||||
|
||||
// Translate the camera go a given point using the dx, dy fraction
|
||||
void translateCamera(float dx, float dy, const Vector3& worldPoint);
|
||||
|
||||
// Get the near clipping plane
|
||||
float getNearClippingPlane() const;
|
||||
|
||||
// Get the far clipping plane
|
||||
float getFarClippingPlane() const;
|
||||
|
||||
// Get the width
|
||||
uint getWidth() const;
|
||||
|
||||
// Get the height
|
||||
uint getHeight() const;
|
||||
};
|
||||
|
||||
// Get the projection matrix
|
||||
inline const Matrix4& Camera::getProjectionMatrix() const {
|
||||
return mProjectionMatrix;
|
||||
}
|
||||
|
||||
// Set the dimensions of the camera
|
||||
inline void Camera::setDimensions(uint width, uint height) {
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// Get the radius of the scene the camera should capture
|
||||
inline float Camera::getSceneRadius() const {
|
||||
return mSceneRadius;
|
||||
}
|
||||
|
||||
// Set the radius of the scene the camera should capture
|
||||
// This will update the clipping planes accordingly
|
||||
inline void Camera::setSceneRadius(float radius) {
|
||||
mSceneRadius = radius;
|
||||
setClippingPlanes(0.01f * radius, 10.0f * radius);
|
||||
}
|
||||
|
||||
// Set the clipping planes
|
||||
inline void Camera::setClippingPlanes(float near, float far) {
|
||||
mNearPlane = near;
|
||||
mFarPlane = far;
|
||||
updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// Set the field of view
|
||||
inline void Camera::setFieldOfView(float fov) {
|
||||
mFieldOfView = fov;
|
||||
updateProjectionMatrix();
|
||||
}
|
||||
|
||||
// Set the zoom of the camera (a fraction between 0 and 1)
|
||||
inline void Camera::setZoom(float fraction) {
|
||||
Vector3 zoomVector(0, 0, mSceneRadius * fraction * 3.0f);
|
||||
translateLocal(zoomVector);
|
||||
}
|
||||
|
||||
// Get the near clipping plane
|
||||
inline float Camera::getNearClippingPlane() const {
|
||||
return mNearPlane;
|
||||
}
|
||||
|
||||
// Get the far clipping plane
|
||||
inline float Camera::getFarClippingPlane() const {
|
||||
return mFarPlane;
|
||||
}
|
||||
|
||||
// Get the width
|
||||
inline uint Camera::getWidth() const {
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
// Get the height
|
||||
inline uint Camera::getHeight() const {
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
115
examples/opengl-framework/src/FrameBufferObject.cpp
Normal file
115
examples/opengl-framework/src/FrameBufferObject.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "FrameBufferObject.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
FrameBufferObject::FrameBufferObject() : mFrameBufferID(0), mRenderBufferID (0) {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
FrameBufferObject::~FrameBufferObject() {
|
||||
|
||||
}
|
||||
|
||||
// Create the frame buffer object
|
||||
bool FrameBufferObject::create(uint width, uint height, bool needRenderBuffer) {
|
||||
|
||||
// Destroy the current FBO
|
||||
destroy();
|
||||
|
||||
// Check that the needed OpenGL extensions are available
|
||||
bool isExtensionOK = checkOpenGLExtensions();
|
||||
if (!isExtensionOK) {
|
||||
std::cerr << "Error : Impossible to use Framebuffer Object on this platform" << std::endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate a new FBO
|
||||
glGenFramebuffersEXT(1, &mFrameBufferID);
|
||||
assert(mFrameBufferID != 0);
|
||||
|
||||
// If we also need to create a render buffer
|
||||
if (needRenderBuffer) {
|
||||
|
||||
// Generate the render buffer
|
||||
glGenRenderbuffers(1, &mRenderBufferID);
|
||||
assert(mRenderBufferID != 0);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, mRenderBufferID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, width, height);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
|
||||
mRenderBufferID);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
// Check the FBO status
|
||||
GLenum statusFBO = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if(statusFBO != GL_FRAMEBUFFER_COMPLETE) {
|
||||
std::cerr << "Error : An error occured while creating the Frame Buffer Object !" << endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Destroy the FBO
|
||||
void FrameBufferObject::destroy() {
|
||||
|
||||
// Delete the frame buffer object
|
||||
if (mFrameBufferID) {
|
||||
glDeleteFramebuffers(1, &mFrameBufferID);
|
||||
mFrameBufferID = 0;
|
||||
}
|
||||
|
||||
// Delete the render buffer
|
||||
if (mRenderBufferID) {
|
||||
glDeleteRenderbuffers(1, &mRenderBufferID);
|
||||
}
|
||||
}
|
||||
|
||||
// Attach a texture to the frame buffer object
|
||||
void FrameBufferObject::attachTexture(uint position, uint textureID) {
|
||||
assert(mFrameBufferID);
|
||||
|
||||
// Bind the current FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID);
|
||||
|
||||
// Bind the texture
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, position, GL_TEXTURE_2D, textureID, 0);
|
||||
|
||||
// Unbind the current FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
105
examples/opengl-framework/src/FrameBufferObject.h
Normal file
105
examples/opengl-framework/src/FrameBufferObject.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef FRAME_BUFFER_OBJECT_H
|
||||
#define FRAME_BUFFER_OBJECT_H
|
||||
|
||||
// Libraries
|
||||
#include "definitions.h"
|
||||
#include <GL/glew.h>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
|
||||
// Class FrameBufferObject
|
||||
class FrameBufferObject {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Frame buffer ID
|
||||
uint mFrameBufferID;
|
||||
|
||||
// Render buffer ID
|
||||
uint mRenderBufferID;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
FrameBufferObject();
|
||||
|
||||
// Destructor
|
||||
~FrameBufferObject();
|
||||
|
||||
// Create the frame buffer object
|
||||
bool create(uint width, uint height, bool needRenderBuffer = true);
|
||||
|
||||
// Attach a texture to the frame buffer object
|
||||
void attachTexture(uint position, uint textureID);
|
||||
|
||||
// Bind the FBO
|
||||
void bind(uint position) const;
|
||||
|
||||
// Unbind the FBO
|
||||
void unbind() const;
|
||||
|
||||
// Return true if the needed OpenGL extensions are available for FBO
|
||||
static bool checkOpenGLExtensions();
|
||||
|
||||
// Destroy the FBO
|
||||
void destroy();
|
||||
};
|
||||
|
||||
// Bind the FBO
|
||||
inline void FrameBufferObject::bind(uint position) const {
|
||||
assert(mFrameBufferID != 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFrameBufferID);
|
||||
glDrawBuffer(position);
|
||||
glReadBuffer(position);
|
||||
}
|
||||
|
||||
// Unbind the FBO
|
||||
inline void FrameBufferObject::unbind() const {
|
||||
assert(mFrameBufferID != 0);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
// Return true if the needed OpenGL extensions are available for FBO
|
||||
inline bool FrameBufferObject::checkOpenGLExtensions() {
|
||||
|
||||
// Check that OpenGL version is at least 3.0 or there the framebuffer object extension exists
|
||||
return (GLEW_VERSION_3_0 || GLEW_ARB_framebuffer_object);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
260
examples/opengl-framework/src/GlutViewer.cpp
Normal file
260
examples/opengl-framework/src/GlutViewer.cpp
Normal file
|
@ -0,0 +1,260 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "GlutViewer.h"
|
||||
#include <string>
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
GlutViewer::GlutViewer() {
|
||||
|
||||
// Initialize the state of the mouse buttons
|
||||
for (int i=0; i<10; i++) {
|
||||
mIsButtonDown[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Destructor
|
||||
GlutViewer::~GlutViewer() {
|
||||
|
||||
}
|
||||
|
||||
// Initialize the viewer
|
||||
bool GlutViewer::init(int argc, char** argv, const string& windowsTitle,
|
||||
const Vector2& windowsSize, const Vector2& windowsPosition,
|
||||
bool isMultisamplingActive) {
|
||||
|
||||
// Initialize the GLUT library
|
||||
bool outputValue = initGLUT(argc, argv, windowsTitle, windowsSize,
|
||||
windowsPosition, isMultisamplingActive);
|
||||
|
||||
// Active the multi-sampling by default
|
||||
if (isMultisamplingActive) {
|
||||
activateMultiSampling(true);
|
||||
}
|
||||
|
||||
return outputValue;
|
||||
}
|
||||
|
||||
// Initialize the GLUT library
|
||||
bool GlutViewer::initGLUT(int argc, char** argv, const string& windowsTitle,
|
||||
const Vector2& windowsSize, const Vector2& windowsPosition,
|
||||
bool isMultisamplingActive) {
|
||||
|
||||
// Initialize GLUT
|
||||
glutInit(&argc, argv);
|
||||
uint modeWithoutMultiSampling = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH;
|
||||
uint modeWithMultiSampling = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GL_MULTISAMPLE;
|
||||
uint displayMode = isMultisamplingActive ? modeWithMultiSampling : modeWithoutMultiSampling;
|
||||
glutInitDisplayMode(displayMode);
|
||||
|
||||
// Initialize the size of the GLUT windows
|
||||
glutInitWindowSize(static_cast<int>(windowsSize.x),
|
||||
static_cast<int>(windowsSize.y));
|
||||
|
||||
// Initialize the position of the GLUT windows
|
||||
glutInitWindowPosition(static_cast<int>(windowsPosition.x),
|
||||
static_cast<int>(windowsPosition.y));
|
||||
|
||||
// Create the GLUT windows
|
||||
glutCreateWindow(windowsTitle.c_str());
|
||||
|
||||
// Initialize the GLEW library
|
||||
GLenum error = glewInit();
|
||||
if (error != GLEW_OK) {
|
||||
|
||||
// Problem: glewInit failed, something is wrong
|
||||
cerr << "GLEW Error : " << glewGetErrorString(error) << std::endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set the camera so that we can view the whole scene
|
||||
void GlutViewer::resetCameraToViewAll() {
|
||||
|
||||
// Move the camera to the origin of the scene
|
||||
mCamera.translateWorld(-mCamera.getOrigin());
|
||||
|
||||
// Move the camera to the center of the scene
|
||||
mCamera.translateWorld(mCenterScene);
|
||||
|
||||
// Set the zoom of the camera so that the scene center is
|
||||
// in negative view direction of the camera
|
||||
mCamera.setZoom(1.0);
|
||||
}
|
||||
|
||||
// Called when a GLUT mouse button event occurs
|
||||
void GlutViewer::mouseButtonEvent(int button, int state, int x, int y) {
|
||||
|
||||
// If the mouse button is pressed
|
||||
if (state == GLUT_DOWN) {
|
||||
mLastMouseX = x;
|
||||
mLastMouseY = y;
|
||||
mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(x, y, mLastPointOnSphere);
|
||||
mIsButtonDown[button] = true;
|
||||
}
|
||||
else { // If the mouse button is released
|
||||
mIsLastPointOnSphereValid = false;
|
||||
mIsButtonDown[button] = false;
|
||||
|
||||
// If it is a mouse wheel click event
|
||||
if (button == 3) {
|
||||
zoom(0, (int) (y - 0.05f * mCamera.getWidth()));
|
||||
}
|
||||
else if (button == 4) {
|
||||
zoom(0, (int) (y + 0.05f * mCamera.getHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
mModifiers = glutGetModifiers();
|
||||
|
||||
// Notify GLUT to redisplay
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
// Called when a GLUT mouse motion event occurs
|
||||
void GlutViewer::mouseMotionEvent(int xMouse, int yMouse) {
|
||||
|
||||
// Zoom
|
||||
if ((mIsButtonDown[GLUT_LEFT_BUTTON] && mIsButtonDown[GLUT_MIDDLE_BUTTON]) ||
|
||||
(mIsButtonDown[GLUT_LEFT_BUTTON] && mModifiers == GLUT_ACTIVE_ALT)) {
|
||||
zoom(xMouse, yMouse);
|
||||
}
|
||||
// Translation
|
||||
else if (mIsButtonDown[GLUT_MIDDLE_BUTTON] || mIsButtonDown[GLUT_RIGHT_BUTTON] ||
|
||||
(mIsButtonDown[GLUT_LEFT_BUTTON] && (mModifiers == GLUT_ACTIVE_ALT))) {
|
||||
translate(xMouse, yMouse);
|
||||
}
|
||||
// Rotation
|
||||
else if (mIsButtonDown[GLUT_LEFT_BUTTON]) {
|
||||
rotate(xMouse, yMouse);
|
||||
}
|
||||
|
||||
// Remember the mouse position
|
||||
mLastMouseX = xMouse;
|
||||
mLastMouseY = yMouse;
|
||||
mIsLastPointOnSphereValid = mapMouseCoordinatesToSphere(xMouse, yMouse, mLastPointOnSphere);
|
||||
|
||||
// Notify GLUT to redisplay
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
// Map the mouse x,y coordinates to a point on a sphere
|
||||
bool GlutViewer::mapMouseCoordinatesToSphere(int xMouse, int yMouse, Vector3& spherePoint) const {
|
||||
|
||||
int width = mCamera.getWidth();
|
||||
int height = mCamera.getHeight();
|
||||
|
||||
if ((xMouse >= 0) && (xMouse <= width) && (yMouse >= 0) && (yMouse <= height)) {
|
||||
float x = float(xMouse - 0.5f * width) / float(width);
|
||||
float y = float(0.5f * height - yMouse) / float(height);
|
||||
float sinx = sin(PI * x * 0.5f);
|
||||
float siny = sin(PI * y * 0.5f);
|
||||
float sinx2siny2 = sinx * sinx + siny * siny;
|
||||
|
||||
// Compute the point on the sphere
|
||||
spherePoint.x = sinx;
|
||||
spherePoint.y = siny;
|
||||
spherePoint.z = (sinx2siny2 < 1.0) ? sqrt(1.0f - sinx2siny2) : 0.0f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Zoom the camera
|
||||
void GlutViewer::zoom(int xMouse, int yMouse) {
|
||||
float dy = static_cast<float>(yMouse - mLastMouseY);
|
||||
float h = static_cast<float>(mCamera.getHeight());
|
||||
|
||||
// Zoom the camera
|
||||
mCamera.setZoom(-dy / h);
|
||||
}
|
||||
|
||||
// Translate the camera
|
||||
void GlutViewer::translate(int xMouse, int yMouse) {
|
||||
float dx = static_cast<float>(xMouse - mLastMouseX);
|
||||
float dy = static_cast<float>(yMouse - mLastMouseY);
|
||||
|
||||
// Translate the camera
|
||||
mCamera.translateCamera(-dx / float(mCamera.getWidth()),
|
||||
-dy / float(mCamera.getHeight()), mCenterScene);
|
||||
}
|
||||
|
||||
// Rotate the camera
|
||||
void GlutViewer::rotate(int xMouse, int yMouse) {
|
||||
|
||||
if (mIsLastPointOnSphereValid) {
|
||||
|
||||
Vector3 newPoint3D;
|
||||
bool isNewPointOK = mapMouseCoordinatesToSphere(xMouse, yMouse, newPoint3D);
|
||||
|
||||
if (isNewPointOK) {
|
||||
Vector3 axis = mLastPointOnSphere.cross(newPoint3D);
|
||||
float cosAngle = mLastPointOnSphere.dot(newPoint3D);
|
||||
|
||||
float epsilon = std::numeric_limits<float>::epsilon();
|
||||
if (fabs(cosAngle) < 1.0f && axis.length() > epsilon) {
|
||||
axis.normalize();
|
||||
float angle = 2.0f * acos(cosAngle);
|
||||
|
||||
// Rotate the camera around the center of the scene
|
||||
mCamera.rotateAroundLocalPoint(axis, -angle, mCenterScene);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check the OpenGL errors
|
||||
void GlutViewer::checkOpenGLErrors() {
|
||||
GLenum glError;
|
||||
|
||||
// Get the OpenGL errors
|
||||
glError = glGetError();
|
||||
|
||||
// While there are errors
|
||||
while (glError != GL_NO_ERROR) {
|
||||
|
||||
// Get the error string
|
||||
const GLubyte* stringError = gluErrorString(glError);
|
||||
|
||||
// Display the error
|
||||
if (stringError)
|
||||
cerr << "OpenGL Error #" << glError << "(" << gluErrorString(glError) << endl;
|
||||
else
|
||||
cerr << "OpenGL Error #" << glError << " (no message available)" << endl;
|
||||
|
||||
// Get the next error
|
||||
glError = glGetError();
|
||||
}
|
||||
}
|
160
examples/opengl-framework/src/GlutViewer.h
Normal file
160
examples/opengl-framework/src/GlutViewer.h
Normal file
|
@ -0,0 +1,160 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef GLUT_VIEWER_H
|
||||
#define GLUT_VIEWER_H
|
||||
|
||||
// Libraries
|
||||
#include "Shader.h"
|
||||
#include "Camera.h"
|
||||
#include "maths/Vector2.h"
|
||||
#include <string>
|
||||
#include <GL/glew.h>
|
||||
#include "GL/freeglut.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Renderer
|
||||
class GlutViewer {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Camera
|
||||
Camera mCamera;
|
||||
|
||||
// Center of the scene
|
||||
Vector3 mCenterScene;
|
||||
|
||||
// Last mouse coordinates on the windows
|
||||
int mLastMouseX, mLastMouseY;
|
||||
|
||||
// Last point computed on a sphere (for camera rotation)
|
||||
Vector3 mLastPointOnSphere;
|
||||
|
||||
// True if the last point computed on a sphere (for camera rotation) is valid
|
||||
bool mIsLastPointOnSphereValid;
|
||||
|
||||
// State of the mouse buttons
|
||||
bool mIsButtonDown[10];
|
||||
|
||||
// GLUT keyboard modifiers
|
||||
int mModifiers;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Initialize the GLUT library
|
||||
bool initGLUT(int argc, char** argv, const std::string& windowsTitle,
|
||||
const Vector2& windowsSize, const Vector2& windowsPosition,
|
||||
bool isMultisamplingActive);
|
||||
|
||||
bool mapMouseCoordinatesToSphere(int xMouse, int yMouse, Vector3& spherePoint) const;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
GlutViewer();
|
||||
|
||||
// Destructor
|
||||
~GlutViewer();
|
||||
|
||||
// Initialize the viewer
|
||||
bool init(int argc, char** argv, const std::string& windowsTitle,
|
||||
const Vector2& windowsSize, const Vector2& windowsPosition,
|
||||
bool isMultisamplingActive = false);
|
||||
|
||||
// Called when the windows is reshaped
|
||||
void reshape(int width, int height);
|
||||
|
||||
// Set the scene position (where the camera needs to look at)
|
||||
void setScenePosition(const Vector3& position, float sceneRadius);
|
||||
|
||||
// Set the camera so that we can view the whole scene
|
||||
void resetCameraToViewAll();
|
||||
|
||||
// Enable/Disable the multi-sampling for anti-aliasing
|
||||
void activateMultiSampling(bool isActive) const;
|
||||
|
||||
// Zoom the camera
|
||||
void zoom(int xMouse, int yMouse);
|
||||
|
||||
// Translate the camera
|
||||
void translate(int xMouse, int yMouse);
|
||||
|
||||
// Rotate the camera
|
||||
void rotate(int xMouse, int yMouse);
|
||||
|
||||
// Get the camera
|
||||
Camera& getCamera();
|
||||
|
||||
void motion(int x, int y);
|
||||
|
||||
// Called when a GLUT mouse button event occurs
|
||||
void mouseButtonEvent(int button, int state, int x, int y);
|
||||
|
||||
// Called when a GLUT mouse motion event occurs
|
||||
void mouseMotionEvent(int xMouse, int yMouse);
|
||||
|
||||
void keyboard(int key, int x, int y);
|
||||
void special(int key, int x, int y);
|
||||
|
||||
// Check the OpenGL errors
|
||||
static void checkOpenGLErrors();
|
||||
};
|
||||
|
||||
// Set the dimension of the camera viewport
|
||||
inline void GlutViewer::reshape(int width, int height) {
|
||||
mCamera.setDimensions(width, height);
|
||||
glViewport(0, 0, width, height);
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
// Set the scene position (where the camera needs to look at)
|
||||
inline void GlutViewer::setScenePosition(const Vector3& position, float sceneRadius) {
|
||||
|
||||
// Set the position and radius of the scene
|
||||
mCenterScene = position;
|
||||
mCamera.setSceneRadius(sceneRadius);
|
||||
|
||||
// Reset the camera position and zoom in order to view all the scene
|
||||
resetCameraToViewAll();
|
||||
}
|
||||
|
||||
// Get the camera
|
||||
inline Camera& GlutViewer::getCamera() {
|
||||
return mCamera;
|
||||
}
|
||||
|
||||
// Enable/Disable the multi-sampling for anti-aliasing
|
||||
inline void GlutViewer::activateMultiSampling(bool isActive) const {
|
||||
(isActive) ? glEnable(GL_MULTISAMPLE) : glDisable(GL_MULTISAMPLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
100
examples/opengl-framework/src/Light.cpp
Normal file
100
examples/opengl-framework/src/Light.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Light.h"
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Light::Light(GLuint id)
|
||||
: mLightID(id), mDiffuseColor(Color::white()),
|
||||
mSpecularColor(Color::white()), mIsActive(false) {
|
||||
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Light::Light(GLuint id, Color diffuseColor, Color specularColor)
|
||||
: mLightID(id), mDiffuseColor(diffuseColor),
|
||||
mSpecularColor(specularColor), mIsActive(false) {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Light::~Light() {
|
||||
|
||||
}
|
||||
|
||||
// Initialize the light
|
||||
void Light::init() {
|
||||
|
||||
// Enable the light
|
||||
enable();
|
||||
|
||||
// Set the diffuse and specular color
|
||||
GLfloat diffuseColor[] = {mDiffuseColor.r, mDiffuseColor.g, mDiffuseColor.b, mDiffuseColor.a};
|
||||
GLfloat specularColor[] = {mSpecularColor.r,mSpecularColor.g,mSpecularColor.b,mSpecularColor.a};
|
||||
glLightfv(mLightID, GL_DIFFUSE, diffuseColor);
|
||||
glLightfv(mLightID, GL_SPECULAR, specularColor);
|
||||
}
|
||||
|
||||
// Create a shadow map associated with this light
|
||||
bool Light::createShadowMap(uint width, uint height) {
|
||||
|
||||
// Destroy the current shadow map
|
||||
destroyShadowMap();
|
||||
|
||||
// Create the Framebuffer object to render the shadow map
|
||||
bool isFBOCreated = mFBOShadowMap.create(width, height, false);
|
||||
if (!isFBOCreated) {
|
||||
std::cerr << "Error : Cannot create the Shadow Map !" << std::endl;
|
||||
destroyShadowMap();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bind the Framebuffer object
|
||||
mFBOShadowMap.bind(GL_NONE);
|
||||
|
||||
// Create the shadow map depth texture
|
||||
mShadowMap.create(width, height, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE);
|
||||
|
||||
// Attache the shadow map texture to the Framebuffer object
|
||||
mFBOShadowMap.attachTexture(GL_DEPTH_ATTACHMENT_EXT, mShadowMap.getID());
|
||||
|
||||
// Unbind the Framebuffer object
|
||||
mFBOShadowMap.unbind();
|
||||
|
||||
// TODO : Change the path of the shader here so that it does not depend on the build folder
|
||||
bool isShaderCreated = mDepthShader.create("../../opengl-framework/src/shaders/depth.vert",
|
||||
"../../opengl-framework/src/shaders/depth.vert");
|
||||
if (!isShaderCreated) {
|
||||
std::cerr << "Error : Cannot create the Shadow Map !" << std::endl;
|
||||
destroyShadowMap();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
181
examples/opengl-framework/src/Light.h
Normal file
181
examples/opengl-framework/src/Light.h
Normal file
|
@ -0,0 +1,181 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef LIGHT_H
|
||||
#define LIGHT_H
|
||||
|
||||
// Libraries
|
||||
#include "maths/Color.h"
|
||||
#include "maths/Vector3.h"
|
||||
#include "Object3D.h"
|
||||
#include "Texture2D.h"
|
||||
#include "FrameBufferObject.h"
|
||||
#include "Shader.h"
|
||||
#include <GL/glew.h>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Light
|
||||
class Light : public Object3D {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// OpenGL light ID
|
||||
GLuint mLightID;
|
||||
|
||||
// Diffuse color of the light
|
||||
Color mDiffuseColor;
|
||||
|
||||
// Specular color of the light
|
||||
Color mSpecularColor;
|
||||
|
||||
// True if the light is active
|
||||
bool mIsActive;
|
||||
|
||||
// Shadow map associated with this light
|
||||
Texture2D mShadowMap;
|
||||
|
||||
// Framebuffer object to render the shadow map
|
||||
FrameBufferObject mFBOShadowMap;
|
||||
|
||||
// Shader to render the depth of the scene into a texture
|
||||
Shader mDepthShader;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Light(GLuint id);
|
||||
|
||||
// Constructor
|
||||
Light(GLuint id, Color diffuseColor, Color specularColor);
|
||||
|
||||
// Destructor
|
||||
virtual ~Light();
|
||||
|
||||
// Return the diffuse color
|
||||
Color getDiffuseColor() const;
|
||||
|
||||
// Set the diffuse color
|
||||
void setDiffuseColor(const Color& color);
|
||||
|
||||
// Return the specular color
|
||||
Color getSpecularColor() const;
|
||||
|
||||
// Set the specular color
|
||||
void setSpecularColor(const Color& color);
|
||||
|
||||
// Return true if the light is active
|
||||
bool getIsActive() const;
|
||||
|
||||
// Initialize the light
|
||||
void init();
|
||||
|
||||
// Enable the light
|
||||
void enable();
|
||||
|
||||
// Disable the light
|
||||
void disable();
|
||||
|
||||
// Create a shadow map associated with this light
|
||||
bool createShadowMap(uint width, uint height);
|
||||
|
||||
// Call this method before rendering the scene for the shadow map computation
|
||||
void startRenderingShadowMap();
|
||||
|
||||
// Call this method after having rendered the scene for the shadow map computation
|
||||
void stopRenderingShadowMap();
|
||||
|
||||
// Destroy the shadow map associated with this light
|
||||
void destroyShadowMap();
|
||||
};
|
||||
|
||||
// Return the diffuse color
|
||||
inline Color Light::getDiffuseColor() const {
|
||||
return mDiffuseColor;
|
||||
}
|
||||
|
||||
// Set the diffuse color
|
||||
inline void Light::setDiffuseColor(const Color& color) {
|
||||
mDiffuseColor = color;
|
||||
}
|
||||
|
||||
// Return the specular color
|
||||
inline Color Light::getSpecularColor() const {
|
||||
return mSpecularColor;
|
||||
}
|
||||
|
||||
// Set the specular color
|
||||
inline void Light::setSpecularColor(const Color& color) {
|
||||
mSpecularColor = color;
|
||||
}
|
||||
|
||||
// Return true if the light is active
|
||||
inline bool Light::getIsActive() const {
|
||||
return mIsActive;
|
||||
}
|
||||
|
||||
// Enable the light
|
||||
inline void Light::enable() {
|
||||
|
||||
mIsActive = true;
|
||||
|
||||
// Enable the light
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0 + mLightID);
|
||||
}
|
||||
|
||||
// Disable the light
|
||||
inline void Light::disable() {
|
||||
|
||||
mIsActive = false;
|
||||
|
||||
// Disable the light
|
||||
glDisable(GL_LIGHT0 + mLightID);
|
||||
}
|
||||
|
||||
// Destroy the shadow map associated with this light
|
||||
inline void Light::destroyShadowMap() {
|
||||
mShadowMap.destroy();
|
||||
mFBOShadowMap.destroy();
|
||||
mDepthShader.destroy();
|
||||
}
|
||||
|
||||
// Call this method before rendering the scene for the shadow map computation
|
||||
inline void Light::startRenderingShadowMap() {
|
||||
assert(mShadowMap.getID());
|
||||
}
|
||||
|
||||
// Call this method after having rendered the scene for the shadow map computation
|
||||
inline void Light::stopRenderingShadowMap() {
|
||||
assert(mShadowMap.getID());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
177
examples/opengl-framework/src/Mesh.cpp
Normal file
177
examples/opengl-framework/src/Mesh.cpp
Normal file
|
@ -0,0 +1,177 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Mesh.h"
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
Mesh::Mesh() {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Mesh::~Mesh() {
|
||||
|
||||
}
|
||||
|
||||
// Destroy the mesh
|
||||
void Mesh::destroy() {
|
||||
|
||||
mVertices.clear();
|
||||
mNormals.clear();
|
||||
mTangents.clear();
|
||||
mIndices.clear();
|
||||
mColors.clear();
|
||||
mUVs.clear();
|
||||
mTextures.clear();
|
||||
}
|
||||
|
||||
// Compute the normals of the mesh
|
||||
void Mesh::calculateNormals() {
|
||||
|
||||
mNormals = vector<Vector3>(getNbVertices(), Vector3(0, 0, 0));
|
||||
|
||||
// For each triangular face
|
||||
for (uint i=0; i<getNbFaces(); i++) {
|
||||
|
||||
// Get the three vertices index of the current face
|
||||
uint v1 = getVertexIndexInFace(i, 0);
|
||||
uint v2 = getVertexIndexInFace(i, 1);
|
||||
uint v3 = getVertexIndexInFace(i, 2);
|
||||
|
||||
assert(v1 < getNbVertices());
|
||||
assert(v2 < getNbVertices());
|
||||
assert(v3 < getNbVertices());
|
||||
|
||||
// Compute the normal of the face
|
||||
Vector3 p = getVertex(v1);
|
||||
Vector3 q = getVertex(v2);
|
||||
Vector3 r = getVertex(v3);
|
||||
Vector3 normal = (q-p).cross(r-p).normalize();
|
||||
|
||||
// Add the face surface normal to the sum of normals at
|
||||
// each vertex of the face
|
||||
mNormals[v1] += normal;
|
||||
mNormals[v2] += normal;
|
||||
mNormals[v3] += normal;
|
||||
}
|
||||
|
||||
// Normalize the normal at each vertex
|
||||
for (uint i=0; i<getNbVertices(); i++) {
|
||||
assert(mNormals[i].length() > 0);
|
||||
mNormals[i] = mNormals[i].normalize();
|
||||
}
|
||||
}
|
||||
|
||||
// Compute the tangents of the mesh
|
||||
void Mesh::calculateTangents() {
|
||||
|
||||
mTangents = std::vector<Vector3>(getNbVertices(), Vector3(0, 0, 0));
|
||||
|
||||
// For each face
|
||||
for (uint i=0; i<getNbFaces(); i++) {
|
||||
|
||||
// Get the three vertices index of the face
|
||||
uint v1 = getVertexIndexInFace(i, 0);
|
||||
uint v2 = getVertexIndexInFace(i, 1);
|
||||
uint v3 = getVertexIndexInFace(i, 2);
|
||||
|
||||
assert(v1 < getNbVertices());
|
||||
assert(v2 < getNbVertices());
|
||||
assert(v3 < getNbVertices());
|
||||
|
||||
// Get the vertices positions
|
||||
Vector3 p = getVertex(v1);
|
||||
Vector3 q = getVertex(v2);
|
||||
Vector3 r = getVertex(v3);
|
||||
|
||||
// Get the texture coordinates of each vertex
|
||||
Vector2 uvP = getUV(v1);
|
||||
Vector2 uvQ = getUV(v2);
|
||||
Vector2 uvR = getUV(v3);
|
||||
|
||||
// Get the three edges
|
||||
Vector3 edge1 = q - p;
|
||||
Vector3 edge2 = r - p;
|
||||
Vector2 edge1UV = uvQ - uvP;
|
||||
Vector2 edge2UV = uvR - uvP;
|
||||
|
||||
float cp = edge1UV.y * edge2UV.x - edge1UV.x * edge2UV.y;
|
||||
|
||||
// Compute the tangent
|
||||
if (cp != 0.0f) {
|
||||
float factor = 1.0f / cp;
|
||||
Vector3 tangent = (edge1 * -edge2UV.y + edge2 * edge1UV.y) * factor;
|
||||
tangent.normalize();
|
||||
mTangents[v1] = tangent;
|
||||
mTangents[v2] = tangent;
|
||||
mTangents[v3] = tangent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the bounding box of the mesh
|
||||
void Mesh::calculateBoundingBox(Vector3& min, Vector3& max) const {
|
||||
|
||||
// If the mesh contains vertices
|
||||
if (!mVertices.empty()) {
|
||||
|
||||
min = mVertices[0];
|
||||
max = mVertices[0];
|
||||
|
||||
std::vector<Vector3>::const_iterator it(mVertices.begin());
|
||||
|
||||
// For each vertex of the mesh
|
||||
for (; it != mVertices.end(); ++it) {
|
||||
|
||||
if( (*it).x < min.x ) min.x = (*it).x;
|
||||
else if ( (*it).x > max.x ) max.x = (*it).x;
|
||||
|
||||
if( (*it).y < min.y ) min.y = (*it).y;
|
||||
else if ( (*it).y > max.y ) max.y = (*it).y;
|
||||
|
||||
if( (*it).z < min.z ) min.z = (*it).z;
|
||||
else if ( (*it).z > max.z ) max.z = (*it).z;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Error : Impossible to calculate the bounding box of the mesh because there" <<
|
||||
"are no vertices !" << std::endl;
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Scale of vertices of the mesh using a given factor
|
||||
void Mesh::scaleVertices(float factor) {
|
||||
|
||||
// For each vertex
|
||||
for (uint i=0; i<getNbVertices(); i++) {
|
||||
mVertices.at(i) *= factor;
|
||||
}
|
||||
}
|
411
examples/opengl-framework/src/Mesh.h
Normal file
411
examples/opengl-framework/src/Mesh.h
Normal file
|
@ -0,0 +1,411 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef MESH_H
|
||||
#define MESH_H
|
||||
|
||||
// Libraries
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "definitions.h"
|
||||
#include "maths/Vector2.h"
|
||||
#include "maths/Vector3.h"
|
||||
#include "maths/Color.h"
|
||||
#include "Texture2D.h"
|
||||
#include "Object3D.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Mesh
|
||||
// This class represents a 3D triangular mesh
|
||||
// object that can be loaded from an OBJ file for instance.
|
||||
class Mesh : public Object3D {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// A triplet of vertex indices for each triangle
|
||||
std::vector<std::vector<uint> > mIndices;
|
||||
|
||||
// Vertices coordinates (local space)
|
||||
std::vector<Vector3> mVertices;
|
||||
|
||||
// Normals coordinates
|
||||
std::vector<Vector3> mNormals;
|
||||
|
||||
// Tangents coordinates
|
||||
std::vector<Vector3> mTangents;
|
||||
|
||||
// Color for each vertex
|
||||
std::vector<Color> mColors;
|
||||
|
||||
// UV texture coordinates
|
||||
std::vector<Vector2> mUVs;
|
||||
|
||||
// Textures of the mesh (one for each part of the mesh)
|
||||
std::map<uint, Texture2D> mTextures;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Mesh();
|
||||
|
||||
// Destructor
|
||||
virtual ~Mesh();
|
||||
|
||||
// Destroy the mesh
|
||||
void destroy();
|
||||
|
||||
// Compute the normals of the mesh
|
||||
void calculateNormals();
|
||||
|
||||
// Compute the tangents of the mesh
|
||||
void calculateTangents();
|
||||
|
||||
// Calculate the bounding box of the mesh
|
||||
void calculateBoundingBox(Vector3& min, Vector3& max) const;
|
||||
|
||||
// Scale of vertices of the mesh using a given factor
|
||||
void scaleVertices(float factor);
|
||||
|
||||
// Return the number of triangles
|
||||
uint getNbFaces(uint part = 0) const;
|
||||
|
||||
// Return the number of vertices
|
||||
uint getNbVertices() const;
|
||||
|
||||
// Return the number of parts in the mesh
|
||||
uint getNbParts() const;
|
||||
|
||||
// Return a reference to the vertices
|
||||
const std::vector<Vector3>& getVertices() const;
|
||||
|
||||
// Set the vertices of the mesh
|
||||
void setVertices(std::vector<Vector3>& vertices);
|
||||
|
||||
// Return a reference to the normals
|
||||
const std::vector<Vector3>& getNormals() const;
|
||||
|
||||
// set the normals of the mesh
|
||||
void setNormals(std::vector<Vector3>& normals);
|
||||
|
||||
// Return a reference to the UVs
|
||||
const std::vector<Vector2>& getUVs() const;
|
||||
|
||||
// Set the UV texture coordinates of the mesh
|
||||
void setUVs(std::vector<Vector2>& uvs);
|
||||
|
||||
// Return a reference to the vertex indices
|
||||
const std::vector<uint>& getIndices(uint part = 0) const;
|
||||
|
||||
// Set the vertices indices of the mesh
|
||||
void setIndices(std::vector<std::vector<uint> >& indices);
|
||||
|
||||
// Return the coordinates of a given vertex
|
||||
const Vector3& getVertex(uint i) const;
|
||||
|
||||
// Set the coordinates of a given vertex
|
||||
void setVertex(uint i, const Vector3& vertex);
|
||||
|
||||
// Return the coordinates of a given normal
|
||||
const Vector3& getNormal(uint i) const;
|
||||
|
||||
// Set the coordinates of a given normal
|
||||
void setNormal(uint i, const Vector3& normal);
|
||||
|
||||
// Return the color of a given vertex
|
||||
const Color& getColor(uint i) const;
|
||||
|
||||
// Set the color of a given vertex
|
||||
void setColor(uint i, const Color& color);
|
||||
|
||||
// Set a color to all the vertices
|
||||
void setColorToAllVertices(const Color& color);
|
||||
|
||||
// Return the UV of a given vertex
|
||||
const Vector2& getUV(uint i) const;
|
||||
|
||||
// Set the UV of a given vertex
|
||||
void setUV(uint i, const Vector2& uv);
|
||||
|
||||
// Return the vertex index of the ith (i=0,1,2) vertex of a given face
|
||||
uint getVertexIndexInFace(uint faceIndex, uint i, uint part = 0) const;
|
||||
|
||||
// Return true if the mesh has normals
|
||||
bool hasNormals() const;
|
||||
|
||||
// Return true if the mesh has tangents
|
||||
bool hasTangents() const;
|
||||
|
||||
// Return true if the mesh has vertex colors
|
||||
bool hasColors() const;
|
||||
|
||||
// Return true if the mesh has UV texture coordinates
|
||||
bool hasUVTextureCoordinates() const;
|
||||
|
||||
// Return true if the mesh has a texture for a given part of the mesh and if it
|
||||
// also have texture coordinates
|
||||
bool hasTextureForPart(uint part = 0) const;
|
||||
|
||||
// Return true if the mesh has a texture (and texture coordinates) for at least one
|
||||
// part of the mesh
|
||||
bool hasTexture() const;
|
||||
|
||||
// Return a pointer to the vertices data
|
||||
void* getVerticesPointer();
|
||||
|
||||
// Return a pointer to the normals data
|
||||
void* getNormalsPointer();
|
||||
|
||||
// Return a pointer to the colors data
|
||||
void* getColorsPointer();
|
||||
|
||||
// Return a pointer to the tangents data
|
||||
void* getTangentsPointer();
|
||||
|
||||
// Return a pointer to the UV texture coordinates data
|
||||
void* getUVTextureCoordinatesPointer();
|
||||
|
||||
// Return a pointer to the vertex indicies data
|
||||
void* getIndicesPointer(uint part = 0);
|
||||
|
||||
// Return a reference to a texture of the mesh
|
||||
Texture2D &getTexture(uint part = 0);
|
||||
|
||||
// Set a texture to a part of the mesh
|
||||
void setTexture(Texture2D &texture, uint part = 0);
|
||||
};
|
||||
|
||||
// Return the number of triangles
|
||||
inline uint Mesh::getNbFaces(uint part) const {
|
||||
return mIndices[part].size() / 3;
|
||||
}
|
||||
|
||||
// Return the number of vertices
|
||||
inline uint Mesh::getNbVertices() const {
|
||||
return mVertices.size();
|
||||
}
|
||||
|
||||
// Return the number of parts in the mesh
|
||||
inline uint Mesh::getNbParts() const {
|
||||
return mIndices.size();
|
||||
}
|
||||
|
||||
// Return a reference to the vertices
|
||||
inline const std::vector<Vector3>& Mesh::getVertices() const {
|
||||
return mVertices;
|
||||
}
|
||||
|
||||
// Set the vertices of the mesh
|
||||
inline void Mesh::setVertices(std::vector<Vector3>& vertices) {
|
||||
mVertices = vertices;
|
||||
}
|
||||
|
||||
// Return a reference to the normals
|
||||
inline const std::vector<Vector3>& Mesh::getNormals() const {
|
||||
return mNormals;
|
||||
}
|
||||
|
||||
// set the normals of the mesh
|
||||
inline void Mesh::setNormals(std::vector<Vector3>& normals) {
|
||||
mNormals = normals;
|
||||
}
|
||||
|
||||
// Return a reference to the UVs
|
||||
inline const std::vector<Vector2>& Mesh::getUVs() const {
|
||||
return mUVs;
|
||||
}
|
||||
|
||||
// Set the UV texture coordinates of the mesh
|
||||
inline void Mesh::setUVs(std::vector<Vector2>& uvs) {
|
||||
mUVs = uvs;
|
||||
}
|
||||
|
||||
// Return a reference to the vertex indices
|
||||
inline const std::vector<uint>& Mesh::getIndices(uint part) const {
|
||||
return mIndices[part];
|
||||
}
|
||||
|
||||
// Set the vertices indices of the mesh
|
||||
inline void Mesh::setIndices(std::vector<std::vector<uint> >& indices) {
|
||||
mIndices = indices;
|
||||
}
|
||||
|
||||
// Return the coordinates of a given vertex
|
||||
inline const Vector3& Mesh::getVertex(uint i) const {
|
||||
assert(i < getNbVertices());
|
||||
return mVertices[i];
|
||||
}
|
||||
|
||||
// Set the coordinates of a given vertex
|
||||
inline void Mesh::setVertex(uint i, const Vector3& vertex) {
|
||||
assert(i < getNbVertices());
|
||||
mVertices[i] = vertex;
|
||||
}
|
||||
|
||||
// Return the coordinates of a given normal
|
||||
inline const Vector3& Mesh::getNormal(uint i) const {
|
||||
assert(i < getNbVertices());
|
||||
return mNormals[i];
|
||||
}
|
||||
|
||||
// Set the coordinates of a given normal
|
||||
inline void Mesh::setNormal(uint i, const Vector3& normal) {
|
||||
assert(i < getNbVertices());
|
||||
mNormals[i] = normal;
|
||||
}
|
||||
|
||||
// Return the color of a given vertex
|
||||
inline const Color& Mesh::getColor(uint i) const {
|
||||
assert(i < getNbVertices());
|
||||
return mColors[i];
|
||||
}
|
||||
|
||||
// Set the color of a given vertex
|
||||
inline void Mesh::setColor(uint i, const Color& color) {
|
||||
|
||||
// If the color array does not have the same size as
|
||||
// the vertices array
|
||||
if (mColors.size() != mVertices.size()) {
|
||||
|
||||
// Create the color array with the same size
|
||||
mColors = std::vector<Color>(mVertices.size());
|
||||
}
|
||||
|
||||
mColors[i] = color;
|
||||
}
|
||||
|
||||
// Set a color to all the vertices
|
||||
inline void Mesh::setColorToAllVertices(const Color& color) {
|
||||
|
||||
// If the color array does not have the same size as
|
||||
// the vertices array
|
||||
if (mColors.size() != mVertices.size()) {
|
||||
|
||||
// Create the color array with the same size
|
||||
mColors = std::vector<Color>(mVertices.size());
|
||||
}
|
||||
|
||||
for (size_t v=0; v<mVertices.size(); v++) {
|
||||
mColors[v] = color;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the UV of a given vertex
|
||||
inline const Vector2& Mesh::getUV(uint i) const {
|
||||
assert(i < getNbVertices());
|
||||
return mUVs[i];
|
||||
}
|
||||
|
||||
// Set the UV of a given vertex
|
||||
inline void Mesh::setUV(uint i, const Vector2& uv) {
|
||||
assert(i < getNbVertices());
|
||||
mUVs[i] = uv;
|
||||
}
|
||||
|
||||
// Return the vertex index of the ith (i=0,1,2) vertex of a given face
|
||||
inline uint Mesh::getVertexIndexInFace(uint faceIndex, uint i, uint part) const {
|
||||
return (mIndices[part])[faceIndex*3 + i];
|
||||
}
|
||||
|
||||
// Return true if the mesh has normals
|
||||
inline bool Mesh::hasNormals() const {
|
||||
return mNormals.size() == mVertices.size();
|
||||
}
|
||||
|
||||
// Return true if the mesh has tangents
|
||||
inline bool Mesh::hasTangents() const {
|
||||
return mTangents.size() == mVertices.size();
|
||||
}
|
||||
|
||||
// Return true if the mesh has vertex colors
|
||||
inline bool Mesh::hasColors() const {
|
||||
return mColors.size() == mVertices.size();
|
||||
}
|
||||
|
||||
// Return true if the mesh has UV texture coordinates
|
||||
inline bool Mesh::hasUVTextureCoordinates() const {
|
||||
return mUVs.size() == mVertices.size();
|
||||
}
|
||||
|
||||
// Return true if the mesh has a texture for a given part of the mesh and if it
|
||||
// also have texture coordinates
|
||||
inline bool Mesh::hasTextureForPart(uint part) const {
|
||||
return hasUVTextureCoordinates() && mTextures.count(part);
|
||||
}
|
||||
|
||||
// Return true if the mesh has a texture (and texture coordinates) for at least one
|
||||
// part of the mesh
|
||||
inline bool Mesh::hasTexture() const {
|
||||
return hasUVTextureCoordinates() && (mTextures.size() > 0);
|
||||
}
|
||||
|
||||
// Return a pointer to the vertices data
|
||||
inline void* Mesh::getVerticesPointer() {
|
||||
return &(mVertices[0]);
|
||||
}
|
||||
|
||||
// Return a pointer to the normals data
|
||||
inline void* Mesh::getNormalsPointer() {
|
||||
return &(mNormals[0]);
|
||||
}
|
||||
|
||||
// Return a pointer to the colors data
|
||||
inline void* Mesh::getColorsPointer() {
|
||||
return &(mColors[0]);
|
||||
}
|
||||
|
||||
// Return a pointer to the tangents data
|
||||
inline void* Mesh::getTangentsPointer() {
|
||||
return &(mTangents[0]);
|
||||
}
|
||||
|
||||
// Return a pointer to the UV texture coordinates data
|
||||
inline void* Mesh::getUVTextureCoordinatesPointer() {
|
||||
return &(mUVs[0]);
|
||||
}
|
||||
|
||||
// Return a pointer to the vertex indicies data
|
||||
inline void* Mesh::getIndicesPointer(uint part) {
|
||||
return &(mIndices[part])[0];
|
||||
}
|
||||
|
||||
// Return a reference to a texture of the mesh
|
||||
inline Texture2D& Mesh::getTexture(uint part) {
|
||||
return mTextures[part];
|
||||
}
|
||||
|
||||
// Set a texture to a part of the mesh
|
||||
inline void Mesh::setTexture(Texture2D& texture, uint part) {
|
||||
mTextures[part] = texture;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
397
examples/opengl-framework/src/MeshReaderWriter.cpp
Normal file
397
examples/opengl-framework/src/MeshReaderWriter.cpp
Normal file
|
@ -0,0 +1,397 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "MeshReaderWriter.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <locale>
|
||||
#include <cctype>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
MeshReaderWriter::MeshReaderWriter() {
|
||||
|
||||
}
|
||||
|
||||
// Load a mesh from a file and returns true if the mesh has been sucessfully loaded
|
||||
void MeshReaderWriter::loadMeshFromFile(const std::string& filename,
|
||||
Mesh& meshToCreate)
|
||||
throw(std::invalid_argument, std::runtime_error) {
|
||||
|
||||
// Get the extension of the file
|
||||
uint startPosExtension = filename.find_last_of(".");
|
||||
string extension = filename.substr(startPosExtension+1);
|
||||
|
||||
// Load the file using the correct method
|
||||
if (extension == "obj") {
|
||||
loadOBJFile(filename, meshToCreate);
|
||||
}
|
||||
else {
|
||||
|
||||
// Display an error message and throw an exception
|
||||
string errorMessage("Error : the MeshReaderWriter class cannot load a file with the extension .");
|
||||
errorMessage += extension;
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::invalid_argument(errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Write a mesh to a file
|
||||
void MeshReaderWriter::writeMeshToFile(const std::string& filename,
|
||||
const Mesh& meshToWrite)
|
||||
throw(std::invalid_argument, std::runtime_error) {
|
||||
|
||||
// Get the extension of the file
|
||||
uint startPosExtension = filename.find_last_of(".");
|
||||
string extension = filename.substr(startPosExtension+1);
|
||||
|
||||
// Load the file using the correct method
|
||||
if (extension == "obj") {
|
||||
writeOBJFile(filename, meshToWrite);
|
||||
}
|
||||
else {
|
||||
|
||||
// Display an error message and throw an exception
|
||||
string errorMessage("Error : the MeshReaderWriter class cannot store a mesh file with the extension .");
|
||||
errorMessage += extension;
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::invalid_argument(errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Load an OBJ file with a triangular or quad mesh
|
||||
void MeshReaderWriter::loadOBJFile(const string &filename, Mesh& meshToCreate) {
|
||||
|
||||
// Open the file
|
||||
std::ifstream meshFile(filename.c_str());
|
||||
|
||||
// If we cannot open the file
|
||||
if(!meshFile.is_open()) {
|
||||
|
||||
// Throw an exception and display an error message
|
||||
string errorMessage("Error : Cannot open the file " + filename);
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
std::string buffer;
|
||||
string line, tmp;
|
||||
int id1, id2, id3, id4;
|
||||
int nId1, nId2, nId3, nId4;
|
||||
int tId1, tId2, tId3, tId4;
|
||||
float v1, v2, v3;
|
||||
size_t found1, found2;
|
||||
std::vector<bool> isQuad;
|
||||
std::vector<Vector3> vertices;
|
||||
std::vector<Vector3> normals;
|
||||
std::vector<Vector2> uvs;
|
||||
std::vector<uint> verticesIndices;
|
||||
std::vector<uint> normalsIndices;
|
||||
std::vector<uint> uvsIndices;
|
||||
|
||||
// ---------- Collect the data from the file ---------- //
|
||||
|
||||
// For each line of the file
|
||||
while(std::getline(meshFile, buffer)) {
|
||||
|
||||
std::istringstream lineStream(buffer);
|
||||
std::string word;
|
||||
lineStream >> word;
|
||||
std::transform(word.begin(), word.end(), word.begin(), ::tolower);
|
||||
if(word == "usemtl") { // Material definition
|
||||
|
||||
// Loading of MTL file is not implemented
|
||||
|
||||
}
|
||||
else if(word == "v") { // Vertex position
|
||||
sscanf(buffer.c_str(), "%*s %f %f %f", &v1, &v2, &v3);
|
||||
vertices.push_back(Vector3(v1, v2, v3));
|
||||
}
|
||||
else if(word == "vt") { // Vertex texture coordinate
|
||||
sscanf(buffer.c_str(), "%*s %f %f", &v1, &v2);
|
||||
uvs.push_back(Vector2(v1,v2));
|
||||
}
|
||||
else if(word == "vn") { // Vertex normal
|
||||
sscanf(buffer.c_str(), "%*s %f %f %f", &v1, &v2, &v3);
|
||||
normals.push_back(Vector3(v1 ,v2, v3));
|
||||
}
|
||||
else if (word == "f") { // Face
|
||||
line = buffer;
|
||||
found1 = (int)line.find("/");
|
||||
bool isFaceQuad = false;
|
||||
int foundNext = (int)line.substr(found1+1).find("/");
|
||||
|
||||
// If the face definition is of the form "f v1 v2 v3 v4"
|
||||
if(found1 == string::npos) {
|
||||
int nbVertices = sscanf(buffer.c_str(), "%*s %d %d %d %d", &id1, &id2, &id3, &id4);
|
||||
if (nbVertices == 4) isFaceQuad = true;
|
||||
}
|
||||
// If the face definition is of the form "f v1// v2// v3// v4//"
|
||||
else if (foundNext == 0) {
|
||||
int nbVertices = sscanf(buffer.c_str(), "%*s %d// %d// %d// %d//", &id1, &id2, &id3, &id4);
|
||||
if (nbVertices == 4) isFaceQuad = true;
|
||||
}
|
||||
else { // If the face definition contains vertices and texture coordinates
|
||||
|
||||
//get the part of the string until the second index
|
||||
tmp = line.substr(found1+1);
|
||||
found2 = (int)tmp.find(" ");
|
||||
tmp = tmp.substr(0,found2);
|
||||
found2 = (int)tmp.find("/");
|
||||
|
||||
// If the face definition is of the form "f vert1/textcoord1 vert2/textcoord2 ..."
|
||||
if(found2 == string::npos) {
|
||||
int n = sscanf(buffer.c_str(), "%*s %d/%d %d/%d %d/%d %d/%d", &id1, &tId1, &id2, &tId2, &id3, &tId3, &id4, &tId4);
|
||||
if (n == 8) isFaceQuad = true;
|
||||
uvsIndices.push_back(tId1-1);
|
||||
uvsIndices.push_back(tId2-1);
|
||||
uvsIndices.push_back(tId3-1);
|
||||
if (isFaceQuad) uvsIndices.push_back(tId4-1);
|
||||
}
|
||||
else {
|
||||
tmp = line.substr(found1+1);
|
||||
found2 = (int)tmp.find("/");
|
||||
|
||||
// If the face definition is of the form "f vert1/normal1 vert2/normal2 ..."
|
||||
if(found2 == 0) {
|
||||
int n = sscanf(buffer.c_str(), "%*s %d//%d %d//%d %d//%d %d//%d", &id1, &nId1, &id2, &nId2, &id3, &nId3, &id4, &nId4);
|
||||
if (n == 8) isFaceQuad = true;
|
||||
}
|
||||
// If the face definition is of the form "f vert1/textcoord1/normal1 ..."
|
||||
else {
|
||||
int n = sscanf(buffer.c_str(), "%*s %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", &id1, &tId1, &nId1, &id2, &tId2, &nId2, &id3, &tId3, &nId3, &id4, &tId4, &nId4);
|
||||
if (n == 12) isFaceQuad = true;
|
||||
uvsIndices.push_back(tId1-1);
|
||||
uvsIndices.push_back(tId2-1);
|
||||
uvsIndices.push_back(tId3-1);
|
||||
if (isFaceQuad) uvsIndices.push_back(tId4-1);
|
||||
}
|
||||
normalsIndices.push_back(nId1-1);
|
||||
normalsIndices.push_back(nId2-1);
|
||||
normalsIndices.push_back(nId3-1);
|
||||
if (isFaceQuad) normalsIndices.push_back(nId4-1);
|
||||
}
|
||||
}
|
||||
verticesIndices.push_back(id1-1);
|
||||
verticesIndices.push_back(id2-1);
|
||||
verticesIndices.push_back(id3-1);
|
||||
if (isFaceQuad) verticesIndices.push_back((id4-1));
|
||||
isQuad.push_back(isFaceQuad);
|
||||
}
|
||||
}
|
||||
|
||||
assert(!verticesIndices.empty());
|
||||
assert(normalsIndices.empty() || normalsIndices.size() == verticesIndices.size());
|
||||
assert(uvsIndices.empty() || uvsIndices.size() == verticesIndices.size());
|
||||
meshFile.close();
|
||||
|
||||
// ---------- Merge the data that we have collected from the file ---------- //
|
||||
|
||||
// Destroy the current mesh
|
||||
meshToCreate.destroy();
|
||||
|
||||
// Mesh data
|
||||
vector<std::vector<uint> > meshIndices;
|
||||
vector<Vector3> meshNormals;
|
||||
if (!normals.empty()) meshNormals = vector<Vector3>(vertices.size(), Vector3(0, 0, 0));
|
||||
vector<Vector2> meshUVs;
|
||||
if (!uvs.empty()) meshUVs = vector<Vector2>(vertices.size(), Vector2(0, 0));
|
||||
|
||||
// We cannot load mesh with several parts for the moment
|
||||
uint meshPart = 0;
|
||||
|
||||
// Fill in the vertex indices
|
||||
// We also triangulate each quad face
|
||||
meshIndices.push_back(std::vector<uint>());
|
||||
for(size_t i = 0, j = 0; i < verticesIndices.size(); j++) {
|
||||
|
||||
// Get the current vertex IDs
|
||||
uint i1 = verticesIndices[i];
|
||||
uint i2 = verticesIndices[i+1];
|
||||
uint i3 = verticesIndices[i+2];
|
||||
|
||||
// Add the vertex normal
|
||||
if (!normalsIndices.empty() && !normals.empty()) {
|
||||
meshNormals[i1] = normals[normalsIndices[i]];
|
||||
meshNormals[i2] = normals[normalsIndices[i+1]];
|
||||
meshNormals[i3] = normals[normalsIndices[i+2]];
|
||||
}
|
||||
|
||||
// Add the vertex UV texture coordinates
|
||||
if (!uvsIndices.empty() && !uvs.empty()) {
|
||||
meshUVs[i1] = uvs[uvsIndices[i]];
|
||||
meshUVs[i2] = uvs[uvsIndices[i+1]];
|
||||
meshUVs[i3] = uvs[uvsIndices[i+2]];
|
||||
}
|
||||
|
||||
// If the current vertex not in a quad (it is part of a triangle)
|
||||
if (!isQuad[j]) {
|
||||
|
||||
// Add the vertex indices
|
||||
meshIndices[meshPart].push_back(i1);
|
||||
meshIndices[meshPart].push_back(i2);
|
||||
meshIndices[meshPart].push_back(i3);
|
||||
|
||||
i+=3;
|
||||
}
|
||||
else { // If the current vertex is in a quad
|
||||
|
||||
Vector3 v1 = vertices[i1];
|
||||
Vector3 v2 = vertices[i2];
|
||||
Vector3 v3 = vertices[i3];
|
||||
uint i4 = verticesIndices[i+3];
|
||||
Vector3 v4 = vertices[i4];
|
||||
|
||||
Vector3 v13 = v3-v1;
|
||||
Vector3 v12 = v2-v1;
|
||||
Vector3 v14 = v4-v1;
|
||||
|
||||
float a1 = v13.dot(v12);
|
||||
float a2 = v13.dot(v14);
|
||||
if((a1 >= 0 && a2 <= 0) || (a1 <= 0 && a2 >= 0)) {
|
||||
meshIndices[meshPart].push_back(i1);
|
||||
meshIndices[meshPart].push_back(i2);
|
||||
meshIndices[meshPart].push_back(i3);
|
||||
meshIndices[meshPart].push_back(i1);
|
||||
meshIndices[meshPart].push_back(i3);
|
||||
meshIndices[meshPart].push_back(i4);
|
||||
}
|
||||
else {
|
||||
meshIndices[meshPart].push_back(i1);
|
||||
meshIndices[meshPart].push_back(i2);
|
||||
meshIndices[meshPart].push_back(i4);
|
||||
meshIndices[meshPart].push_back(i2);
|
||||
meshIndices[meshPart].push_back(i3);
|
||||
meshIndices[meshPart].push_back(i4);
|
||||
}
|
||||
|
||||
// Add the vertex normal
|
||||
if (!normalsIndices.empty() && !normals.empty()) {
|
||||
meshNormals[i4] = normals[normalsIndices[i]];
|
||||
}
|
||||
|
||||
// Add the vertex UV texture coordinates
|
||||
if (!uvsIndices.empty() && !uvs.empty()) {
|
||||
meshUVs[i4] = uvs[uvsIndices[i]];
|
||||
}
|
||||
|
||||
i+=4;
|
||||
}
|
||||
}
|
||||
|
||||
assert(meshNormals.empty() || meshNormals.size() == vertices.size());
|
||||
assert(meshUVs.empty() || meshUVs.size() == vertices.size());
|
||||
|
||||
// Set the data to the mesh
|
||||
meshToCreate.setIndices(meshIndices);
|
||||
meshToCreate.setVertices(vertices);
|
||||
meshToCreate.setNormals(meshNormals);
|
||||
meshToCreate.setUVs(meshUVs);
|
||||
}
|
||||
|
||||
// Store a mesh into a OBJ file
|
||||
void MeshReaderWriter::writeOBJFile(const std::string& filename, const Mesh& meshToWrite) {
|
||||
std::ofstream file(filename.c_str());
|
||||
|
||||
// Geth the mesh data
|
||||
const std::vector<Vector3>& vertices = meshToWrite.getVertices();
|
||||
const std::vector<Vector3>& normals = meshToWrite.getNormals();
|
||||
const std::vector<Vector2>& uvs = meshToWrite.getUVs();
|
||||
|
||||
// If we can open the file
|
||||
if (file.is_open()) {
|
||||
|
||||
assert(meshToWrite.getNbVertices() == vertices.size());
|
||||
|
||||
// Write the vertices
|
||||
for (uint v=0; v<vertices.size(); v++) {
|
||||
|
||||
file << "v " << vertices[v].x << " " << vertices[v].y << " " << vertices[v].z <<
|
||||
std::endl;
|
||||
}
|
||||
|
||||
// Write the normals
|
||||
if (meshToWrite.hasNormals()) {
|
||||
file << std::endl;
|
||||
|
||||
assert(meshToWrite.getNbVertices() == normals.size());
|
||||
|
||||
for (uint v=0; v<normals.size(); v++) {
|
||||
|
||||
file << "vn " << normals[v].x << " " << normals[v].y << " " << normals[v].z <<
|
||||
std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Write the UVs texture coordinates
|
||||
if (meshToWrite.hasUVTextureCoordinates()) {
|
||||
file << std::endl;
|
||||
|
||||
assert(meshToWrite.getNbVertices() == uvs.size());
|
||||
|
||||
for (uint v=0; v<uvs.size(); v++) {
|
||||
|
||||
file << "vt " << uvs[v].x << " " << uvs[v].y << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Write the faces
|
||||
file << std::endl;
|
||||
for (uint p=0; p<meshToWrite.getNbParts(); p++) {
|
||||
|
||||
// Get the indices of the part
|
||||
const std::vector<uint>& indices = meshToWrite.getIndices(p);
|
||||
|
||||
// For each index of the part
|
||||
for (uint i=0; i<indices.size(); i+=3) {
|
||||
|
||||
if (meshToWrite.hasNormals() && meshToWrite.hasUVTextureCoordinates()) {
|
||||
file << "f " <<indices[i]+1 << "/" << indices[i]+1 << "/" << indices[i]+1 <<
|
||||
" " << indices[i+1]+1 << "/" << indices[i+1]+1 << "/" << indices[i+1]+1 <<
|
||||
" " << indices[i+2]+1 << "/" << indices[i+2]+1 << "/" << indices[i+2]+1 <<
|
||||
std::endl;
|
||||
}
|
||||
else if (meshToWrite.hasNormals() || meshToWrite.hasUVTextureCoordinates()) {
|
||||
file << "f " <<indices[i]+1 << "/" << indices[i]+1 <<
|
||||
" " << indices[i+1]+1 << "/" << indices[i+1]+1 <<
|
||||
" " << indices[i+2]+1 << "/" << indices[i+2]+1 << std::endl;
|
||||
}
|
||||
else {
|
||||
file << "f " << indices[i]+1 << " " << indices[i+1]+1 << " " << indices[i+2]+1 <<
|
||||
std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Error : Cannot open the file " << filename << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
100
examples/opengl-framework/src/MeshReaderWriter.h
Normal file
100
examples/opengl-framework/src/MeshReaderWriter.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef MESH_LOADER_H
|
||||
#define MESH_LOADER_H
|
||||
|
||||
// Libraries
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include "Mesh.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class MeshReaderWriter
|
||||
// This class is used to read or write any mesh file in order to
|
||||
// create the corresponding Mesh object. Currently, this class
|
||||
// is able to read meshes of the current formats : .obj
|
||||
class MeshReaderWriter {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor (private because we do not want instances of this class)
|
||||
MeshReaderWriter();
|
||||
|
||||
// Load an OBJ file with a triangular or quad mesh
|
||||
static void loadOBJFile(const std::string& filename, Mesh& meshToCreate);
|
||||
|
||||
// Store a mesh into a OBJ file
|
||||
static void writeOBJFile(const std::string& filename, const Mesh &meshToWrite);
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Read a mesh from a file
|
||||
static void loadMeshFromFile(const std::string& filename,
|
||||
Mesh& meshToCreate)
|
||||
throw(std::invalid_argument, std::runtime_error);
|
||||
|
||||
// Write a mesh to a file
|
||||
static void writeMeshToFile(const std::string& filename,
|
||||
const Mesh& meshToWrite)
|
||||
throw(std::invalid_argument, std::runtime_error);
|
||||
};
|
||||
|
||||
// Class VertexMergingData
|
||||
// This class is used in the method to read a mesh
|
||||
class VertexMergingData {
|
||||
|
||||
public:
|
||||
VertexMergingData() : indexPosition(0), indexNormal(0), indexUV(0) {}
|
||||
unsigned int indexPosition;
|
||||
unsigned int indexNormal;
|
||||
unsigned int indexUV;
|
||||
};
|
||||
|
||||
// Class VertexMergingDataComparison
|
||||
// This class is used in the method to read a mesh
|
||||
class VertexMergingDataComparison {
|
||||
|
||||
public:
|
||||
bool operator()(const VertexMergingData& x, const VertexMergingData& y) const {
|
||||
if(x.indexPosition < y.indexPosition)
|
||||
return true;
|
||||
if(x.indexPosition == y.indexPosition && x.indexNormal < y.indexNormal)
|
||||
return true;
|
||||
if(x.indexPosition == y.indexPosition && x.indexNormal ==
|
||||
y.indexNormal && x.indexUV < y.indexUV)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
41
examples/opengl-framework/src/Object3D.cpp
Normal file
41
examples/opengl-framework/src/Object3D.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Object3D.h"
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Object3D::Object3D() {
|
||||
// Set the transformation matrix to the identity
|
||||
setToIdentity();
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Object3D::~Object3D() {
|
||||
|
||||
}
|
149
examples/opengl-framework/src/Object3D.h
Normal file
149
examples/opengl-framework/src/Object3D.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef OBJECT3D_H
|
||||
#define OBJECT3D_H
|
||||
|
||||
// Libraries
|
||||
#include "maths/Vector3.h"
|
||||
#include "maths/Matrix4.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Object3D
|
||||
// This class represent a generic 3D object on the scene.
|
||||
class Object3D {
|
||||
|
||||
protected:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Transformation matrix that convert local-space
|
||||
// coordinates to world-space coordinates
|
||||
Matrix4 mTransformMatrix;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Object3D();
|
||||
|
||||
// Destructor
|
||||
virtual ~Object3D();
|
||||
|
||||
// Return the transform matrix
|
||||
const Matrix4& getTransformMatrix() const;
|
||||
|
||||
// Set the transform matrix
|
||||
void setTransformMatrix(const Matrix4& matrix);
|
||||
|
||||
// Set to the identity transform
|
||||
void setToIdentity();
|
||||
|
||||
// Return the origin of object in world-space
|
||||
Vector3 getOrigin() const;
|
||||
|
||||
// Translate the object in world-space
|
||||
void translateWorld(const Vector3& v);
|
||||
|
||||
// Translate the object in local-space
|
||||
void translateLocal(const Vector3& v);
|
||||
|
||||
// Rotate the object in world-space
|
||||
void rotateWorld(const Vector3& axis, float angle);
|
||||
|
||||
// Rotate the object in local-space
|
||||
void rotateLocal(const Vector3& axis, float angle);
|
||||
|
||||
// Rotate around a world-space point
|
||||
void rotateAroundWorldPoint(const Vector3& axis, float angle, const Vector3& point);
|
||||
|
||||
// Rotate around a local-space point
|
||||
void rotateAroundLocalPoint(const Vector3& axis, float angle, const Vector3& worldPoint);
|
||||
};
|
||||
|
||||
// Return the transform matrix
|
||||
inline const Matrix4& Object3D::getTransformMatrix() const {
|
||||
return mTransformMatrix;
|
||||
}
|
||||
|
||||
// Set the transform matrix
|
||||
inline void Object3D::setTransformMatrix(const Matrix4& matrix) {
|
||||
mTransformMatrix = matrix;
|
||||
}
|
||||
|
||||
// Set to the identity transform
|
||||
inline void Object3D::setToIdentity() {
|
||||
mTransformMatrix.setToIdentity();
|
||||
}
|
||||
|
||||
// Return the origin of object in world-space
|
||||
inline Vector3 Object3D::getOrigin() const {
|
||||
return mTransformMatrix * Vector3(0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
// Translate the object in world-space
|
||||
inline void Object3D::translateWorld(const Vector3& v) {
|
||||
mTransformMatrix = Matrix4::translationMatrix(v) * mTransformMatrix;
|
||||
}
|
||||
|
||||
// Translate the object in local-space
|
||||
inline void Object3D::translateLocal(const Vector3& v) {
|
||||
mTransformMatrix = mTransformMatrix * Matrix4::translationMatrix(v);
|
||||
}
|
||||
|
||||
// Rotate the object in world-space
|
||||
inline void Object3D::rotateWorld(const Vector3& axis, float angle) {
|
||||
mTransformMatrix = Matrix4::rotationMatrix(axis, angle) * mTransformMatrix;
|
||||
}
|
||||
|
||||
// Rotate the object in local-space
|
||||
inline void Object3D::rotateLocal(const Vector3& axis, float angle) {
|
||||
mTransformMatrix = mTransformMatrix * Matrix4::rotationMatrix(axis, angle);
|
||||
}
|
||||
|
||||
// Rotate the object around a world-space point
|
||||
inline void Object3D::rotateAroundWorldPoint(const Vector3& axis, float angle,
|
||||
const Vector3& worldPoint) {
|
||||
mTransformMatrix = Matrix4::translationMatrix(worldPoint) * Matrix4::rotationMatrix(axis, angle)
|
||||
* Matrix4::translationMatrix(-worldPoint) * mTransformMatrix;
|
||||
}
|
||||
|
||||
// Rotate the object around a local-space point
|
||||
inline void Object3D::rotateAroundLocalPoint(const Vector3& axis, float angle,
|
||||
const Vector3& worldPoint) {
|
||||
|
||||
// Convert the world point into the local coordinate system
|
||||
Vector3 localPoint = mTransformMatrix.getInverse() * worldPoint;
|
||||
|
||||
mTransformMatrix = mTransformMatrix * Matrix4::translationMatrix(localPoint)
|
||||
* Matrix4::rotationMatrix(axis, angle)
|
||||
* Matrix4::translationMatrix(-localPoint);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
207
examples/opengl-framework/src/Shader.cpp
Normal file
207
examples/opengl-framework/src/Shader.cpp
Normal file
|
@ -0,0 +1,207 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Shader.h"
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constructor
|
||||
Shader::Shader() : mProgramObjectID(0) {
|
||||
|
||||
}
|
||||
|
||||
// Constructor with arguments
|
||||
Shader::Shader(const std::string vertexShaderFilename, const std::string fragmentShaderFilename)
|
||||
: mProgramObjectID(0) {
|
||||
|
||||
// Create the shader
|
||||
create(vertexShaderFilename, fragmentShaderFilename);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Shader::~Shader() {
|
||||
|
||||
}
|
||||
|
||||
// Create the shader
|
||||
bool Shader::create(const std::string vertexShaderFilename,
|
||||
const std::string fragmentShaderFilename) {
|
||||
|
||||
// Set the shader filenames
|
||||
mFilenameVertexShader = vertexShaderFilename;
|
||||
mFilenameFragmentShader = fragmentShaderFilename;
|
||||
|
||||
// Check that the needed OpenGL extensions are available
|
||||
bool isExtensionOK = checkOpenGLExtensions();
|
||||
if (!isExtensionOK) {
|
||||
cerr << "Error : Impossible to use GLSL vertex or fragment shaders on this platform" << endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Delete the current shader
|
||||
destroy();
|
||||
|
||||
assert(!vertexShaderFilename.empty() && !fragmentShaderFilename.empty());
|
||||
|
||||
// ------------------- Load the vertex shader ------------------- //
|
||||
GLuint vertexShaderID;
|
||||
std::ifstream fileVertexShader;
|
||||
fileVertexShader.open(vertexShaderFilename.c_str(), std::ios::binary);
|
||||
|
||||
if (fileVertexShader.is_open()) {
|
||||
|
||||
// Get the size of the file
|
||||
fileVertexShader.seekg(0, std::ios::end);
|
||||
uint fileSize = (uint) (fileVertexShader.tellg());
|
||||
assert(fileSize != 0);
|
||||
|
||||
// Read the file
|
||||
fileVertexShader.seekg(std::ios::beg);
|
||||
char* bufferVertexShader = new char[fileSize + 1];
|
||||
fileVertexShader.read(bufferVertexShader, fileSize);
|
||||
fileVertexShader.close();
|
||||
bufferVertexShader[fileSize] = '\0';
|
||||
|
||||
// Create the OpenGL vertex shader and compile it
|
||||
vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
|
||||
assert(vertexShaderID != 0);
|
||||
glShaderSource(vertexShaderID, 1, (const char **) (&bufferVertexShader), NULL);
|
||||
glCompileShader(vertexShaderID);
|
||||
delete[] bufferVertexShader;
|
||||
|
||||
// Get the compilation information
|
||||
int compiled;
|
||||
glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &compiled);
|
||||
|
||||
// If the compilation failed
|
||||
if (compiled == 0) {
|
||||
|
||||
// Get the log of the compilation
|
||||
int lengthLog;
|
||||
glGetShaderiv(vertexShaderID, GL_INFO_LOG_LENGTH, &lengthLog);
|
||||
char* str = new char[lengthLog];
|
||||
glGetShaderInfoLog(vertexShaderID, lengthLog, NULL, str);
|
||||
|
||||
// Display the log of the compilation
|
||||
std::cerr << "Vertex Shader Error : " << str << std::endl;
|
||||
delete[] str;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Error : Impossible to open the vertex shader file " <<
|
||||
vertexShaderFilename << std::endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------- Load the fragment shader ------------------- //
|
||||
GLuint fragmentShaderID;
|
||||
std::ifstream fileFragmentShader;
|
||||
fileFragmentShader.open(fragmentShaderFilename.c_str(), std::ios::binary);
|
||||
assert(fileFragmentShader.is_open());
|
||||
|
||||
if (fileFragmentShader.is_open()) {
|
||||
|
||||
// Get the size of the file
|
||||
fileFragmentShader.seekg(0, std::ios::end);
|
||||
uint fileSize = (uint) (fileFragmentShader.tellg());
|
||||
assert(fileSize != 0);
|
||||
|
||||
// Read the file
|
||||
fileFragmentShader.seekg(std::ios::beg);
|
||||
char* bufferFragmentShader = new char[fileSize + 1];
|
||||
fileFragmentShader.read(bufferFragmentShader, fileSize);
|
||||
fileFragmentShader.close();
|
||||
bufferFragmentShader[fileSize] = '\0';
|
||||
|
||||
// Create the OpenGL fragment shader and compile it
|
||||
fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
assert(fragmentShaderID != 0);
|
||||
glShaderSource(fragmentShaderID, 1, (const char **) (&bufferFragmentShader), NULL);
|
||||
glCompileShader(fragmentShaderID);
|
||||
delete[] bufferFragmentShader;
|
||||
|
||||
// Get the compilation information
|
||||
int compiled;
|
||||
glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &compiled);
|
||||
|
||||
// If the compilation failed
|
||||
if (compiled == 0) {
|
||||
|
||||
// Get the log of the compilation
|
||||
int lengthLog;
|
||||
glGetShaderiv(fragmentShaderID, GL_INFO_LOG_LENGTH, &lengthLog);
|
||||
char* str = new char[lengthLog];
|
||||
glGetShaderInfoLog(fragmentShaderID, lengthLog, NULL, str);
|
||||
|
||||
// Display the log of the compilation
|
||||
std::cerr << "Fragment Shader Error : " << str << std::endl;
|
||||
delete[] str;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cerr << "Error : Impossible to open the fragment shader file " <<
|
||||
fragmentShaderFilename << std::endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the shader program and attach the shaders
|
||||
mProgramObjectID = glCreateProgram();
|
||||
assert(mProgramObjectID);
|
||||
glAttachShader(mProgramObjectID, vertexShaderID);
|
||||
glAttachShader(mProgramObjectID, fragmentShaderID);
|
||||
glDeleteShader(vertexShaderID);
|
||||
glDeleteShader(fragmentShaderID);
|
||||
|
||||
// Try to link the program
|
||||
glLinkProgram(mProgramObjectID);
|
||||
int linked;
|
||||
glGetProgramiv(mProgramObjectID, GL_LINK_STATUS, &linked);
|
||||
if (!linked) {
|
||||
int logLength;
|
||||
glGetProgramiv(mProgramObjectID, GL_INFO_LOG_LENGTH, &logLength);
|
||||
char* strLog = new char[logLength];
|
||||
glGetProgramInfoLog(mProgramObjectID, logLength, NULL, strLog);
|
||||
cerr << "Linker Error in vertex shader " << vertexShaderFilename <<
|
||||
" or in fragment shader " << fragmentShaderFilename << " : " << strLog << endl;
|
||||
delete[] strLog;
|
||||
destroy();
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
243
examples/opengl-framework/src/Shader.h
Normal file
243
examples/opengl-framework/src/Shader.h
Normal file
|
@ -0,0 +1,243 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef SHADER_H
|
||||
#define SHADER_H
|
||||
|
||||
// Libraries
|
||||
#include "definitions.h"
|
||||
#include "maths/Matrix4.h"
|
||||
#include "maths/Vector2.h"
|
||||
#include "maths/Vector3.h"
|
||||
#include "maths/Vector4.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <GL/glew.h>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Shader
|
||||
class Shader {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Shader object program ID
|
||||
GLuint mProgramObjectID;
|
||||
|
||||
// Filenames of the vertex and fragment shaders
|
||||
std::string mFilenameVertexShader, mFilenameFragmentShader;
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Shader();
|
||||
|
||||
// Constructor with arguments
|
||||
Shader(const std::string vertexShaderFilename, const std::string fragmentShaderFilename);
|
||||
|
||||
// Destructor
|
||||
~Shader();
|
||||
|
||||
// Create the shader
|
||||
bool create(const std::string vertexShaderFilename,
|
||||
const std::string fragmentShaderFilename);
|
||||
|
||||
// Clear the shader
|
||||
void destroy();
|
||||
|
||||
// Bind the shader
|
||||
void bind() const;
|
||||
|
||||
// Unbind the shader
|
||||
void unbind() const;
|
||||
|
||||
// Return the location of a uniform variable inside a shader program
|
||||
int getUniformLocation(const std::string& variableName) const;
|
||||
|
||||
// Set a float uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setFloatUniform(const std::string& variableName, float value) const;
|
||||
|
||||
// Set an int uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setIntUniform(const std::string& variableName, int value) const;
|
||||
|
||||
// Set a vector 2 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setVector2Uniform(const std::string& variableName, const Vector2& v) const;
|
||||
|
||||
// Set a vector 3 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setVector3Uniform(const std::string& variableName, const Vector3& v) const;
|
||||
|
||||
// Set a vector 4 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setVector4Uniform(const std::string& variableName, const Vector4 &v) const;
|
||||
|
||||
// Set a 3x3 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setMatrix3x3Uniform(const std::string& variableName, const float* matrix,
|
||||
bool transpose = false) const;
|
||||
|
||||
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setMatrix4x4Uniform(const std::string& variableName, const float* matrix,
|
||||
bool transpose = false) const;
|
||||
|
||||
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
void setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const;
|
||||
|
||||
// Return true if the needed OpenGL extensions are available
|
||||
static bool checkOpenGLExtensions();
|
||||
};
|
||||
|
||||
// Bind the shader
|
||||
inline void Shader::bind() const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUseProgram(mProgramObjectID);
|
||||
}
|
||||
|
||||
// Unbind the shader
|
||||
inline void Shader::unbind() const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
// Return the location of a uniform variable inside a shader program
|
||||
inline int Shader::getUniformLocation(const std::string& variableName) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
int location = glGetUniformLocation(mProgramObjectID, variableName.c_str());
|
||||
if (location == -1) {
|
||||
std::cerr << "Error in vertex shader " << mFilenameVertexShader << " or in fragment shader"
|
||||
<< mFilenameFragmentShader << " : No Uniform variable : " << variableName
|
||||
<< std::endl;
|
||||
}
|
||||
assert(location != -1);
|
||||
return location;
|
||||
}
|
||||
|
||||
// Clear the shader
|
||||
inline void Shader::destroy() {
|
||||
if (mProgramObjectID != 0) {
|
||||
glDeleteShader(mProgramObjectID);
|
||||
mProgramObjectID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Set a float uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setFloatUniform(const std::string& variableName, float value) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniform1f(getUniformLocation(variableName), value);
|
||||
}
|
||||
|
||||
// Set an int uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setIntUniform(const std::string& variableName, int value) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniform1i(getUniformLocation(variableName), value);
|
||||
}
|
||||
|
||||
// Set a vector 2 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setVector2Uniform(const std::string& variableName, const Vector2& v) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniform2f(getUniformLocation(variableName), v.x, v.y);
|
||||
}
|
||||
|
||||
// Set a vector 3 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setVector3Uniform(const std::string& variableName, const Vector3 &v) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniform3f(getUniformLocation(variableName), v.x, v.y, v.z);
|
||||
}
|
||||
|
||||
// Set a vector 4 uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setVector4Uniform(const std::string& variableName, const Vector4& v) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniform4f(getUniformLocation(variableName), v.x, v.y, v.z, v.w);
|
||||
}
|
||||
|
||||
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setMatrix3x3Uniform(const std::string& variableName, const float* matrix,
|
||||
bool transpose) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniformMatrix3fv(getUniformLocation(variableName), 1, transpose, matrix);
|
||||
}
|
||||
|
||||
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const float* matrix,
|
||||
bool transpose) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
glUniformMatrix4fv(getUniformLocation(variableName), 1, transpose, matrix);
|
||||
}
|
||||
|
||||
// Set a 4x4 matrix uniform value to this shader (be careful if the uniform is not
|
||||
// used in the shader, the compiler will remove it, then when you will try
|
||||
// to set it, an assert will occur)
|
||||
inline void Shader::setMatrix4x4Uniform(const std::string& variableName, const Matrix4& matrix) const {
|
||||
assert(mProgramObjectID != 0);
|
||||
GLfloat mat[16];
|
||||
for (int i=0; i<4; i++) {
|
||||
for (int j=0; j<4; j++) {
|
||||
mat[i*4 + j] = matrix.m[i][j];
|
||||
}
|
||||
}
|
||||
glUniformMatrix4fv(getUniformLocation(variableName), 1, true, mat);
|
||||
}
|
||||
|
||||
// Return true if the needed OpenGL extensions are available for shaders
|
||||
inline bool Shader::checkOpenGLExtensions() {
|
||||
|
||||
// Check that GLSL vertex and fragment shaders are available on the platform
|
||||
return (GLEW_VERSION_2_0 || (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
84
examples/opengl-framework/src/Texture2D.cpp
Normal file
84
examples/opengl-framework/src/Texture2D.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "Texture2D.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// Namespaces
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
Texture2D::Texture2D() : mID(0), mLayer(0), mWidth(0), mHeight(0) {
|
||||
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Texture2D::Texture2D(uint width, uint height, uint internalFormat, uint format, uint type)
|
||||
: mID(0), mLayer(0), mWidth(0), mHeight(0){
|
||||
|
||||
// Create the texture
|
||||
create(width, height, internalFormat, format, type);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Texture2D::~Texture2D() {
|
||||
|
||||
}
|
||||
|
||||
// Create the texture
|
||||
void Texture2D::create(uint width, uint height, uint internalFormat, uint format, uint type,
|
||||
void* data) throw(std::invalid_argument) {
|
||||
|
||||
// Destroy the current texture
|
||||
destroy();
|
||||
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
|
||||
// Create the OpenGL texture
|
||||
glGenTextures(1, &mID);
|
||||
assert(mID != 0);
|
||||
glBindTexture(GL_TEXTURE_2D, mID);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, mWidth, mHeight, 0, format, type, data);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
// Destroy the texture
|
||||
void Texture2D::destroy() {
|
||||
if (mID != 0) {
|
||||
glDeleteTextures(1, &mID);
|
||||
mID = 0;
|
||||
mLayer = 0;
|
||||
mWidth = 0;
|
||||
mHeight = 0;
|
||||
}
|
||||
}
|
142
examples/opengl-framework/src/Texture2D.h
Normal file
142
examples/opengl-framework/src/Texture2D.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEXTURE2D_H
|
||||
#define TEXTURE2D_H
|
||||
|
||||
// Libraries
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include "definitions.h"
|
||||
#include <GL/glew.h>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Texture2D
|
||||
// This class represents a 2D texture
|
||||
class Texture2D {
|
||||
|
||||
private:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// OpenGL texture ID
|
||||
GLuint mID;
|
||||
|
||||
// Layer of the texture
|
||||
GLuint mLayer;
|
||||
|
||||
// Width
|
||||
uint mWidth;
|
||||
|
||||
// Height
|
||||
uint mHeight;
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Texture2D();
|
||||
|
||||
// Constructor
|
||||
Texture2D(uint width, uint height, uint internalFormat, uint format, uint type);
|
||||
|
||||
// Destructor
|
||||
~Texture2D();
|
||||
|
||||
// Create the texture
|
||||
void create(uint width, uint height, uint internalFormat, uint format, uint type,
|
||||
void* data = NULL) throw(std::invalid_argument);
|
||||
|
||||
// Destroy the texture
|
||||
void destroy();
|
||||
|
||||
// Bind the texture
|
||||
void bind() const;
|
||||
|
||||
// Unbind the texture
|
||||
void unbind() const;
|
||||
|
||||
// Get the OpenGL texture ID
|
||||
uint getID() const;
|
||||
|
||||
// Get the layer of the texture
|
||||
uint getLayer() const;
|
||||
|
||||
// Set the layer of the texture
|
||||
void setLayer(uint layer);
|
||||
|
||||
// Get the width
|
||||
uint getWidth() const;
|
||||
|
||||
// Get the height
|
||||
uint getHeight() const;
|
||||
};
|
||||
|
||||
// Bind the texture
|
||||
inline void Texture2D::bind() const {
|
||||
assert(mID != 0);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glActiveTexture(GL_TEXTURE0 + mLayer);
|
||||
glBindTexture(GL_TEXTURE_2D, mID);
|
||||
}
|
||||
|
||||
// Unbind the texture
|
||||
inline void Texture2D::unbind() const {
|
||||
assert(mID != 0);
|
||||
glActiveTexture(GL_TEXTURE0 + mLayer);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
// Get the OpenGL texture ID
|
||||
inline uint Texture2D::getID() const {
|
||||
return mID;
|
||||
}
|
||||
|
||||
// Get the layer of the texture
|
||||
inline uint Texture2D::getLayer() const {
|
||||
return mLayer;
|
||||
}
|
||||
|
||||
// Set the layer of the texture
|
||||
inline void Texture2D::setLayer(uint layer) {
|
||||
mLayer = layer;
|
||||
}
|
||||
|
||||
// Get the width
|
||||
inline uint Texture2D::getWidth() const {
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
// Get the height
|
||||
inline uint Texture2D::getHeight() const {
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
329
examples/opengl-framework/src/TextureReaderWriter.cpp
Normal file
329
examples/opengl-framework/src/TextureReaderWriter.cpp
Normal file
|
@ -0,0 +1,329 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Librairies
|
||||
#include "TextureReaderWriter.h"
|
||||
#include <string>
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
|
||||
using namespace openglframework;
|
||||
using namespace std;
|
||||
|
||||
// Constants
|
||||
const uint TextureReaderWriter::JPEG_COMPRESSION_QUALITY = 98;
|
||||
|
||||
// TGA file Header
|
||||
#pragma pack(push, 1)
|
||||
typedef struct {
|
||||
unsigned char identsize; // size of ID field that follows 18 byte header (0 usually)
|
||||
unsigned char colourmaptype; // type of colour map 0=none, 1=has palette
|
||||
unsigned char imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
|
||||
|
||||
short colourmapstart; // first colour map entry in palette
|
||||
short colourmaplength; // number of colours in palette
|
||||
unsigned char colourmapbits; // number of bits per palette entry 15,16,24,32
|
||||
|
||||
short xstart; // image x origin
|
||||
short ystart; // image y origin
|
||||
short width; // image width in pixels
|
||||
short height; // image height in pixels
|
||||
unsigned char bits; // image bits per pixel 8,16,24,32
|
||||
unsigned char descriptor; // image descriptor bits (vh flip bits)
|
||||
|
||||
// pixel data follows header
|
||||
} TGA_HEADER;
|
||||
#pragma pack(pop)
|
||||
|
||||
// Load a texture from a file
|
||||
void TextureReaderWriter::loadTextureFromFile(const std::string& filename,
|
||||
Texture2D& textureToCreate)
|
||||
throw(runtime_error, invalid_argument){
|
||||
|
||||
// Get the extension of the file
|
||||
uint startPosExtension = filename.find_last_of(".");
|
||||
string extension = filename.substr(startPosExtension+1);
|
||||
|
||||
// Load the file using the correct method
|
||||
if (extension == "tga") {
|
||||
readTGAPicture(filename, textureToCreate);
|
||||
}
|
||||
else if (extension == "jpg" || extension == "jpeg"){
|
||||
readJPEGPicture(filename, textureToCreate);
|
||||
}
|
||||
else {
|
||||
|
||||
// Display an error message and throw an exception
|
||||
string errorMessage("Error : the TextureLoader class cannot load a file with the extension .");
|
||||
errorMessage += extension;
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::invalid_argument(errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Write a texture to a file
|
||||
void TextureReaderWriter::writeTextureToFile(const std::string& filename,
|
||||
const Texture2D& texture)
|
||||
throw(runtime_error, invalid_argument){
|
||||
|
||||
// Get the extension of the file
|
||||
uint startPosExtension = filename.find_last_of(".");
|
||||
string extension = filename.substr(startPosExtension+1);
|
||||
|
||||
// Write the file using the correct method
|
||||
if (extension == "tga") {
|
||||
writeTGAPicture(filename, texture);
|
||||
}
|
||||
else if (extension == "jpg" || extension == "jpeg"){
|
||||
writeJPEGPicture(filename, texture);
|
||||
}
|
||||
else {
|
||||
|
||||
// Display an error message and throw an exception
|
||||
string errorMessage("Error : the TextureReaderWriter class cannot write a file with the extension .");
|
||||
errorMessage += extension;
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::invalid_argument(errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Load a TGA picture
|
||||
void TextureReaderWriter::readTGAPicture(const std::string &filename,
|
||||
Texture2D& textureToCreate) throw(runtime_error) {
|
||||
|
||||
// Open the file
|
||||
std::ifstream stream(filename.c_str(), std::ios::binary);
|
||||
|
||||
// If we cannot open the file
|
||||
if(!stream.is_open()) {
|
||||
|
||||
// Throw an exception and display an error message
|
||||
string errorMessage("Error : Cannot open the file " + filename);
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
TGA_HEADER header;
|
||||
stream.read((char *)(&header), sizeof(TGA_HEADER));
|
||||
assert(header.width <= 4096 && header.width <= 4096 &&
|
||||
header.imagetype == 2 && header.bits == 24);
|
||||
|
||||
// Read the file
|
||||
uint width = header.width;
|
||||
uint height = header.width;
|
||||
uint sizeImg = width*height;
|
||||
char* data = new char[sizeImg*3];
|
||||
assert(data);
|
||||
stream.read(data, sizeImg*3);
|
||||
for(uint i = 0; i < sizeImg; i++) {
|
||||
unsigned pos = i*3;
|
||||
unsigned char red = data[pos];
|
||||
data[pos] = data[pos + 2];
|
||||
data[pos + 2] = red;
|
||||
}
|
||||
|
||||
// Close the stream
|
||||
stream.close();
|
||||
|
||||
// Create the OpenGL texture using the picture data from the file
|
||||
textureToCreate.create(width, height, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
// Free the data memory
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
|
||||
// Write a TGA picture
|
||||
void TextureReaderWriter::writeTGAPicture(const std::string& filename,
|
||||
const Texture2D& texture) throw(runtime_error) {
|
||||
assert(texture.getID() != 0);
|
||||
|
||||
// Bind the corresponding texture
|
||||
glBindTexture(GL_TEXTURE_2D, texture.getID());
|
||||
|
||||
uint sizeImg = texture.getWidth() * texture.getHeight();
|
||||
|
||||
// Get the bytes form the OpenGL texture
|
||||
char* data = new char[sizeImg * 3];
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
// Open the file
|
||||
std::ofstream stream(filename.c_str(), std::ios::binary);
|
||||
|
||||
// If the file cannot be opened
|
||||
if(!stream.is_open()) {
|
||||
|
||||
// Throw an exception and display an error message
|
||||
string errorMessage("Error : Cannot create/access the file " + filename);
|
||||
std::cerr << errorMessage << std::endl;
|
||||
delete[] data;
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
// Fill in the TGA header
|
||||
TGA_HEADER header;
|
||||
header.identsize = 0; // size of ID field that follows 18 byte header (0 usually)
|
||||
header.colourmaptype = 0; // type of colour map 0=none, 1=has palette
|
||||
header.imagetype = 2; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed
|
||||
header.colourmapstart = 0; // first colour map entry in palette
|
||||
header.colourmaplength = 0; // number of colours in palette
|
||||
header.colourmapbits=0; // number of bits per palette entry 15,16,24,32
|
||||
header.xstart = 0; // image x origin
|
||||
header.ystart = 0; // image y origin
|
||||
header.width = (short)texture.getWidth(); // image width in pixels
|
||||
header.height = (short)texture.getHeight(); // image height in pixels
|
||||
header.bits = 24; // image bits per pixel 8,16,24,32
|
||||
header.descriptor = 0; // image descriptor bits (vh flip bits)
|
||||
|
||||
// Write the header to the file
|
||||
stream.write((char*)(&header), sizeof(TGA_HEADER));
|
||||
|
||||
// Write the bytes to the file
|
||||
for(uint i = 0; i < sizeImg; i++) {
|
||||
unsigned pos = i*3;
|
||||
unsigned char red = data[pos];
|
||||
data[pos] = data[pos + 2];
|
||||
data[pos + 2] = red;
|
||||
}
|
||||
stream.write(data, sizeImg*3);
|
||||
|
||||
// Close the file
|
||||
stream.close();
|
||||
|
||||
// Delete the data
|
||||
delete[] data;
|
||||
|
||||
// Unbind the corresponding texture
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
// Read a JPEG picture
|
||||
void TextureReaderWriter::readJPEGPicture(const std::string& filename,
|
||||
Texture2D& textureToCreate) throw(std::runtime_error) {
|
||||
|
||||
struct jpeg_decompress_struct info;
|
||||
struct jpeg_error_mgr error;
|
||||
|
||||
info.err = jpeg_std_error(&error);
|
||||
jpeg_create_decompress(&info);
|
||||
|
||||
// Open the file
|
||||
FILE* file = fopen(filename.c_str(), "rb");
|
||||
|
||||
// If we cannot open the file
|
||||
if (!file) {
|
||||
|
||||
// Throw an exception and display an error message
|
||||
string errorMessage("Error : Cannot open the file " + filename);
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
jpeg_stdio_src(&info, file);
|
||||
jpeg_read_header(&info, true);
|
||||
jpeg_start_decompress(&info);
|
||||
|
||||
unsigned long x = info.output_width;
|
||||
unsigned long y = info.output_height;
|
||||
int channels = info.num_components;
|
||||
assert(channels == 3);
|
||||
|
||||
unsigned long size = x * y * 3;
|
||||
|
||||
BYTE* data = new BYTE[size];
|
||||
|
||||
BYTE* p1 = data;
|
||||
BYTE** p2 = &p1;
|
||||
int numlines = 0;
|
||||
|
||||
while(info.output_scanline < info.output_height) {
|
||||
numlines = jpeg_read_scanlines(&info, p2, 1);
|
||||
*p2 += numlines * 3 * info.output_width;
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&info); //finish decompressing this file
|
||||
|
||||
// Close the file
|
||||
fclose(file);
|
||||
|
||||
// Create the OpenGL texture
|
||||
textureToCreate.create(x, y, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
// Free allocated memory
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
// Write a JPEG picture
|
||||
void TextureReaderWriter::writeJPEGPicture(const std::string& filename,
|
||||
const Texture2D& texture) throw(std::runtime_error) {
|
||||
|
||||
struct jpeg_compress_struct info;
|
||||
struct jpeg_error_mgr error;
|
||||
|
||||
info.err = jpeg_std_error(&error);
|
||||
jpeg_create_compress(&info);
|
||||
|
||||
// Open the file
|
||||
FILE* file = fopen(filename.c_str(), "wb");
|
||||
|
||||
if (!file) {
|
||||
// Throw an exception and display an error message
|
||||
string errorMessage("Error : Cannot write JPEG picture into the file " + filename);
|
||||
std::cerr << errorMessage << std::endl;
|
||||
throw std::runtime_error(errorMessage);
|
||||
}
|
||||
|
||||
// Get the bytes form the OpenGL texture
|
||||
char* data = new char[texture.getWidth() * texture.getHeight() * 3];
|
||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
|
||||
jpeg_stdio_dest(&info, file);
|
||||
|
||||
info.image_width = texture.getWidth();
|
||||
info.image_height = texture.getHeight();
|
||||
info.input_components = 3;
|
||||
info.in_color_space = JCS_RGB;
|
||||
jpeg_set_defaults(&info);
|
||||
jpeg_set_quality(&info, JPEG_COMPRESSION_QUALITY, true);
|
||||
|
||||
jpeg_start_compress(&info, true);
|
||||
|
||||
// Write the data into the file
|
||||
JSAMPROW rowPointer;
|
||||
int rowStride = texture.getWidth() * 3;
|
||||
while (info.next_scanline < info.image_height) {
|
||||
rowPointer = (JSAMPROW) &data[info.next_scanline * rowStride];
|
||||
jpeg_write_scanlines(&info, &rowPointer, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_compress(&info);
|
||||
jpeg_destroy_compress(&info);
|
||||
|
||||
// Close the file
|
||||
fclose(file);
|
||||
|
||||
// Free allocated memory
|
||||
delete[] data;
|
||||
}
|
87
examples/opengl-framework/src/TextureReaderWriter.h
Normal file
87
examples/opengl-framework/src/TextureReaderWriter.h
Normal file
|
@ -0,0 +1,87 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef TEXTURE_READER_WRITER_H
|
||||
#define TEXTURE_READER_WRITER_H
|
||||
|
||||
// Libraries
|
||||
#include "Texture2D.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class TextureReaderWriter
|
||||
// This class is used to load or write a texture image in different picture format.
|
||||
// It currently allows to read and write the following formats : .tga
|
||||
class TextureReaderWriter {
|
||||
|
||||
private :
|
||||
|
||||
// ------------------- Constants ------------------- //
|
||||
|
||||
// JPEG quality for compression (in percent)
|
||||
static const uint JPEG_COMPRESSION_QUALITY;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor (private because we do not want instances of this class)
|
||||
TextureReaderWriter();
|
||||
|
||||
// Read a TGA picture
|
||||
static void readTGAPicture(const std::string& filename,
|
||||
Texture2D& textureToCreate) throw(std::runtime_error);
|
||||
|
||||
// Write a TGA picture
|
||||
static void writeTGAPicture(const std::string& filename,
|
||||
const Texture2D& texture) throw(std::runtime_error);
|
||||
|
||||
// Read a JPEG picture
|
||||
static void readJPEGPicture(const std::string& filename,
|
||||
Texture2D& textureToCreate) throw(std::runtime_error);
|
||||
|
||||
// Write a JPEG picture
|
||||
static void writeJPEGPicture(const std::string& filename,
|
||||
const Texture2D& texture) throw(std::runtime_error);
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Load a texture from a file
|
||||
static void loadTextureFromFile(const std::string& filename,
|
||||
Texture2D& textureToCreate)
|
||||
throw(std::runtime_error, std::invalid_argument);
|
||||
|
||||
// Write a texture to a file
|
||||
static void writeTextureToFile(const std::string& filename,
|
||||
const Texture2D& texture)
|
||||
throw(std::runtime_error, std::invalid_argument);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
84
examples/opengl-framework/src/VertexBufferObject.cpp
Normal file
84
examples/opengl-framework/src/VertexBufferObject.cpp
Normal file
|
@ -0,0 +1,84 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Libraries
|
||||
#include "VertexBufferObject.h"
|
||||
|
||||
using namespace openglframework;
|
||||
|
||||
// Constructor
|
||||
VertexBufferObject::VertexBufferObject(GLenum targetData)
|
||||
: mVertexBufferID(0), mTargetData(targetData) {
|
||||
|
||||
}
|
||||
|
||||
// Destructor
|
||||
VertexBufferObject::~VertexBufferObject() {
|
||||
|
||||
}
|
||||
|
||||
// Create the vertex buffer object
|
||||
bool VertexBufferObject::create() {
|
||||
|
||||
// Destroy the current VBO
|
||||
destroy();
|
||||
|
||||
// Check that the needed OpenGL extensions are available
|
||||
bool isExtensionOK = checkOpenGLExtensions();
|
||||
if (!isExtensionOK) {
|
||||
std::cerr << "Error : Impossible to use Vertex Buffer Object on this platform" << std::endl;
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate a new VBO
|
||||
glGenBuffers(1, &mVertexBufferID);
|
||||
assert(mVertexBufferID != 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copy data into the VBO
|
||||
void VertexBufferObject::copyDataIntoVBO(GLsizei size, const void* data, GLenum usage) {
|
||||
|
||||
// Bind the VBO
|
||||
bind();
|
||||
|
||||
// Copy the data into the VBO
|
||||
glBufferData(mTargetData, size, data, usage);
|
||||
|
||||
// Unbind the VBO
|
||||
unbind();
|
||||
}
|
||||
|
||||
// Destroy the VBO
|
||||
void VertexBufferObject::destroy() {
|
||||
|
||||
// Delete the vertex buffer object
|
||||
if (mVertexBufferID) {
|
||||
glDeleteFramebuffers(1, &mVertexBufferID);
|
||||
mVertexBufferID = 0;
|
||||
}
|
||||
}
|
106
examples/opengl-framework/src/VertexBufferObject.h
Normal file
106
examples/opengl-framework/src/VertexBufferObject.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef VERTEX_BUFFER_OBJECT_H
|
||||
#define VERTEX_BUFFER_OBJECT_H
|
||||
|
||||
// Libraries
|
||||
#include <GL/glew.h>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
|
||||
// Class VertexBufferObject
|
||||
class VertexBufferObject {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
/// ID of the Vertex Buffer Object
|
||||
GLuint mVertexBufferID;
|
||||
|
||||
/// Target data. This variable must be GL_ARRAY_BUFFER if the VBO contains vertex
|
||||
/// data (vertex coordinates, texture coordinates, normals, colors) or must be
|
||||
/// GL_ELEMENT_ARRAY_BUFFER if the VBO contains index data (index array).
|
||||
GLenum mTargetData;
|
||||
|
||||
public :
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
/// Constructor
|
||||
VertexBufferObject(GLenum targetData);
|
||||
|
||||
/// Destructor
|
||||
~VertexBufferObject();
|
||||
|
||||
/// Create the vertex buffer object
|
||||
bool create();
|
||||
|
||||
/// Copy data into the VBO
|
||||
void copyDataIntoVBO(GLsizei size, const void* data, GLenum usage);
|
||||
|
||||
/// Bind the VBO
|
||||
void bind() const;
|
||||
|
||||
/// Unbind the VBO
|
||||
void unbind() const;
|
||||
|
||||
/// Return true if the needed OpenGL extensions are available for VBO
|
||||
static bool checkOpenGLExtensions();
|
||||
|
||||
/// Destroy the VBO
|
||||
void destroy();
|
||||
};
|
||||
|
||||
// Bind the VBO
|
||||
inline void VertexBufferObject::bind() const {
|
||||
assert(mVertexBufferID != 0);
|
||||
|
||||
// Bind the VBO
|
||||
glBindBuffer(mTargetData, mVertexBufferID);
|
||||
}
|
||||
|
||||
// Unbind the VBO
|
||||
inline void VertexBufferObject::unbind() const {
|
||||
assert(mVertexBufferID != 0);
|
||||
|
||||
// Unbind the VBO
|
||||
glBindBuffer(mTargetData, 0);
|
||||
}
|
||||
|
||||
// Return true if the needed OpenGL extensions are available for VBO
|
||||
inline bool VertexBufferObject::checkOpenGLExtensions() {
|
||||
|
||||
// Check that OpenGL version is at least 1.5 or there the vertex buffer object extension exists
|
||||
return (GLEW_VERSION_1_5 || GL_ARB_vertex_buffer_object);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
39
examples/opengl-framework/src/definitions.h
Normal file
39
examples/opengl-framework/src/definitions.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef DEFINITIONS_H
|
||||
#define DEFINITIONS_H
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// ------------------- Type definitions ------------------- //
|
||||
typedef unsigned int uint;
|
||||
|
||||
// ------------------- Constants ------------------- //
|
||||
const float PI = 3.141592654f;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
76
examples/opengl-framework/src/maths/Color.h
Normal file
76
examples/opengl-framework/src/maths/Color.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef COLOR_H
|
||||
#define COLOR_H
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Structure Color
|
||||
// This structure represents a RGBA color.
|
||||
struct Color {
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// RGBA color components
|
||||
float r, g, b, a;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Color() : r(1), g(1), b(1), a(1) {}
|
||||
|
||||
// Constructor
|
||||
Color(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {}
|
||||
|
||||
// Constructor
|
||||
Color(const Color& color) : r(color.r), g(color.g), b(color.b), a(color.a) {}
|
||||
|
||||
// Destructor
|
||||
~Color() {}
|
||||
|
||||
// Return the black color
|
||||
static Color black() { return Color(0.0f, 0.0f, 0.0f, 1.0f);}
|
||||
|
||||
// Return the white color
|
||||
static Color white() { return Color(1.0f, 1.0f, 1.0f, 1.0f);}
|
||||
|
||||
// = operator
|
||||
Color& operator=(const Color& color) {
|
||||
if (&color != this) {
|
||||
r = color.r;
|
||||
g = color.g;
|
||||
b = color.b;
|
||||
a = color.a;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
279
examples/opengl-framework/src/maths/Matrix3.h
Normal file
279
examples/opengl-framework/src/maths/Matrix3.h
Normal file
|
@ -0,0 +1,279 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef MATRIX3_H
|
||||
#define MATRIX3_H
|
||||
|
||||
// Libraries
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include "Vector3.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Matrix4
|
||||
// This class represents a 4x4 matrix
|
||||
class Matrix3 {
|
||||
|
||||
private :
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Elements of the matrix
|
||||
float m[3][3];
|
||||
|
||||
public :
|
||||
|
||||
// Constructor
|
||||
Matrix3() {
|
||||
setToNull();
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix3(float a1, float a2,
|
||||
float a3, float b1, float b2, float b3,
|
||||
float c1, float c2, float c3) {
|
||||
setAllValues(a1, a2, a3, b1, b2, b3, c1, c2, c3);
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix3(float n[3][3]) {
|
||||
m[0][0]=n[0][0]; m[0][1]=n[0][1]; m[0][2]=n[0][2];
|
||||
m[1][0]=n[1][0]; m[1][1]=n[1][1]; m[1][2]=n[1][2];
|
||||
m[2][0]=n[2][0]; m[2][1]=n[2][1]; m[2][2]=n[2][2];
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix3(const Vector3& a1, const Vector3& a2, const Vector3& a3) {
|
||||
m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x;
|
||||
m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y;
|
||||
m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix3(const Matrix3& matrix) {
|
||||
setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2],
|
||||
matrix.m[1][0], matrix.m[1][1], matrix.m[1][2],
|
||||
matrix.m[2][0], matrix.m[2][1], matrix.m[2][2]);
|
||||
}
|
||||
|
||||
// Method to get a value in the matrix
|
||||
float getValue(int i, int j) const {
|
||||
assert(i>=0 && i<3 && j>=0 && j<3);
|
||||
return m[i][j];
|
||||
}
|
||||
|
||||
// Method to set a value in the matrix
|
||||
void setValue(int i, int j, float value) {
|
||||
assert(i>=0 && i<3 && j>=0 && j<3);
|
||||
m[i][j] = value;
|
||||
}
|
||||
|
||||
// Method to set all the values in the matrix
|
||||
void setAllValues(float a1, float a2, float a3, float b1, float b2, float b3,
|
||||
float c1, float c2, float c3) {
|
||||
m[0][0] = a1; m[0][1] = a2; m[0][2] = a3;
|
||||
m[1][0] = b1; m[1][1] = b2; m[1][2] = b3;
|
||||
m[2][0] = c1; m[2][1] = c2; m[2][2] = c3;
|
||||
}
|
||||
|
||||
// Return a column
|
||||
Vector3 getColumn(int i) const {
|
||||
assert(i>= 0 && i<3);
|
||||
return Vector3(m[0][i], m[1][i], m[2][i]);
|
||||
}
|
||||
|
||||
// Return the transpose matrix
|
||||
Matrix3 getTranspose() const {
|
||||
// Return the transpose matrix
|
||||
return Matrix3(m[0][0], m[1][0], m[2][0],
|
||||
m[0][1], m[1][1], m[2][1],
|
||||
m[0][2], m[1][2], m[2][2]);
|
||||
}
|
||||
|
||||
// Return the determinant of the matrix
|
||||
float getDeterminant() const {
|
||||
// Compute and return the determinant of the matrix
|
||||
return (m[0][0]*(m[1][1]*m[2][2]-m[2][1]*m[1][2]) - m[0][1]*(m[1][0]*m[2][2]-m[2][0]*m[1][2]) +
|
||||
m[0][2]*(m[1][0]*m[2][1]-m[2][0]*m[1][1]));
|
||||
}
|
||||
|
||||
// Return the trace of the matrix
|
||||
float getTrace() const {
|
||||
// Compute and return the trace
|
||||
return (m[0][0] + m[1][1] + m[2][2]);
|
||||
}
|
||||
|
||||
void setToNull() {
|
||||
m[0][0] = 0.0; m[0][1] = 0.0; m[0][2] = 0.0;
|
||||
m[1][0] = 0.0; m[1][1] = 0.0; m[1][2] = 0.0;
|
||||
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 0.0;
|
||||
}
|
||||
|
||||
bool isNull() const {
|
||||
Matrix3 zero;
|
||||
return *this == zero;
|
||||
}
|
||||
|
||||
// Set the matrix to the identity matrix
|
||||
void setToIdentity() {
|
||||
m[0][0] = 1.0; m[0][1] = 0.0; m[0][2] = 0.0;
|
||||
m[1][0] = 0.0; m[1][1] = 1.0; m[1][2] = 0.0;
|
||||
m[2][0] = 0.0; m[2][1] = 0.0; m[2][2] = 1.0;
|
||||
}
|
||||
|
||||
bool isIdentity() const {
|
||||
Matrix3 I;
|
||||
I.setToIdentity();
|
||||
return ( *this == I );
|
||||
}
|
||||
|
||||
// Return the inverse matrix
|
||||
Matrix3 getInverse() const {
|
||||
|
||||
// Compute the determinant of the matrix
|
||||
float determinant = getDeterminant();
|
||||
|
||||
// Check if the determinant is equal to zero
|
||||
assert(determinant > std::numeric_limits<float>::epsilon());
|
||||
|
||||
float invDeterminant = 1.0f / determinant;
|
||||
Matrix3 tempMatrix((m[1][1]*m[2][2]-m[2][1]*m[1][2]), -(m[0][1]*m[2][2]-m[2][1]*m[0][2]), (m[0][1]*m[1][2]-m[0][2]*m[1][1]),
|
||||
-(m[1][0]*m[2][2]-m[2][0]*m[1][2]), (m[0][0]*m[2][2]-m[2][0]*m[0][2]), -(m[0][0]*m[1][2]-m[1][0]*m[0][2]),
|
||||
(m[1][0]*m[2][1]-m[2][0]*m[1][1]), -(m[0][0]*m[2][1]-m[2][0]*m[0][1]), (m[0][0]*m[1][1]-m[0][1]*m[1][0]));
|
||||
|
||||
// Return the inverse matrix
|
||||
return (tempMatrix * invDeterminant);
|
||||
}
|
||||
|
||||
// Display the matrix
|
||||
void print() const {
|
||||
for (int i=0; i<3; i++) {
|
||||
for (int j=0; j<3; j++) {
|
||||
std::cout << m[i][j] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Overloaded operator =
|
||||
Matrix3& operator=(const Matrix3& matrix) {
|
||||
if (&matrix != this) {
|
||||
setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2],
|
||||
matrix.m[1][0], matrix.m[1][1], matrix.m[1][2],
|
||||
matrix.m[2][0], matrix.m[2][1], matrix.m[2][2]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Overloaded operator for addition
|
||||
Matrix3 operator+(const Matrix3& matrix2) {
|
||||
return Matrix3(m[0][0] + matrix2.m[0][0], m[0][1] + matrix2.m[0][1], m[0][2] + matrix2.m[0][2],
|
||||
m[1][0] + matrix2.m[1][0], m[1][1] + matrix2.m[1][1], m[1][2] + matrix2.m[1][2],
|
||||
m[2][0] + matrix2.m[2][0], m[2][1] + matrix2.m[2][1], m[2][2] + matrix2.m[2][2]);
|
||||
}
|
||||
|
||||
// Overloaded operator for substraction
|
||||
Matrix3 operator-(const Matrix3& matrix2) {
|
||||
return Matrix3(m[0][0] - matrix2.m[0][0], m[0][1] - matrix2.m[0][1], m[0][2] - matrix2.m[0][2],
|
||||
m[1][0] - matrix2.m[1][0], m[1][1] - matrix2.m[1][1], m[1][2] - matrix2.m[1][2],
|
||||
m[2][0] - matrix2.m[2][0], m[2][1] - matrix2.m[2][1], m[2][2] - matrix2.m[2][2]);
|
||||
}
|
||||
|
||||
// Overloaded operator for the negative of the matrix
|
||||
Matrix3 operator-() {
|
||||
return Matrix3(-m[0][0], -m[0][1], -m[0][2],
|
||||
-m[1][0], -m[1][1], -m[1][2],
|
||||
-m[2][0], -m[2][1], -m[2][2]);
|
||||
}
|
||||
|
||||
// Overloaded operator for multiplication with a number
|
||||
Matrix3 operator*(float nb) {
|
||||
return Matrix3(m[0][0] * nb, m[0][1] * nb, m[0][2] * nb,
|
||||
m[1][0] * nb, m[1][1] * nb, m[1][2] * nb,
|
||||
m[2][0] * nb, m[2][1] * nb, m[2][2] * nb);
|
||||
}
|
||||
|
||||
// Overloaded operator for matrix multiplication
|
||||
Matrix3 operator*(const Matrix3& matrix2) {
|
||||
return Matrix3(m[0][0]*matrix2.m[0][0] + m[0][1]*matrix2.m[1][0] + m[0][2]*matrix2.m[2][0],
|
||||
m[0][0]*matrix2.m[0][1] + m[0][1]*matrix2.m[1][1] + m[0][2]*matrix2.m[2][1],
|
||||
m[0][0]*matrix2.m[0][2] + m[0][1]*matrix2.m[1][2] + m[0][2]*matrix2.m[2][2],
|
||||
m[1][0]*matrix2.m[0][0] + m[1][1]*matrix2.m[1][0] + m[1][2]*matrix2.m[2][0],
|
||||
m[1][0]*matrix2.m[0][1] + m[1][1]*matrix2.m[1][1] + m[1][2]*matrix2.m[2][1],
|
||||
m[1][0]*matrix2.m[0][2] + m[1][1]*matrix2.m[1][2] + m[1][2]*matrix2.m[2][2],
|
||||
m[2][0]*matrix2.m[0][0] + m[2][1]*matrix2.m[1][0] + m[2][2]*matrix2.m[2][0],
|
||||
m[2][0]*matrix2.m[0][1] + m[2][1]*matrix2.m[1][1] + m[2][2]*matrix2.m[2][1],
|
||||
m[2][0]*matrix2.m[0][2] + m[2][1]*matrix2.m[1][2] + m[2][2]*matrix2.m[2][2]);
|
||||
}
|
||||
|
||||
// Overloaded operator for multiplication with a vector
|
||||
Vector3 operator*(const Vector3& vector) {
|
||||
return Vector3(m[0][0]*vector.x + m[0][1]*vector.y + m[0][2]*vector.z,
|
||||
m[1][0]*vector.x + m[1][1]*vector.y + m[1][2]*vector.z,
|
||||
m[2][0]*vector.x + m[2][1]*vector.y + m[2][2]*vector.z);
|
||||
}
|
||||
|
||||
// Overloaded operator for equality condition
|
||||
bool operator==(const Matrix3& matrix) const {
|
||||
return (m[0][0] == matrix.m[0][0] && m[0][1] == matrix.m[0][1] && m[0][2] == matrix.m[0][2] &&
|
||||
m[1][0] == matrix.m[1][0] && m[1][1] == matrix.m[1][1] && m[1][2] == matrix.m[1][2] &&
|
||||
m[2][0] == matrix.m[2][0] && m[2][1] == matrix.m[2][1] && m[2][2] == matrix.m[2][2]);
|
||||
}
|
||||
|
||||
// Overloaded operator for the is different condition
|
||||
bool operator!= (const Matrix3& matrix) const {
|
||||
return !(*this == matrix);
|
||||
}
|
||||
|
||||
// Overloaded operator for addition with assignment
|
||||
Matrix3& operator+=(const Matrix3& matrix) {
|
||||
m[0][0] += matrix.m[0][0]; m[0][1] += matrix.m[0][1]; m[0][2] += matrix.m[0][2];
|
||||
m[1][0] += matrix.m[1][0]; m[1][1] += matrix.m[1][1]; m[1][2] += matrix.m[1][2];
|
||||
m[2][0] += matrix.m[2][0]; m[2][1] += matrix.m[2][1]; m[2][2] += matrix.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Overloaded operator for substraction with assignment
|
||||
Matrix3& operator-=(const Matrix3& matrix) {
|
||||
m[0][0] -= matrix.m[0][0]; m[0][1] -= matrix.m[0][1]; m[0][2] -= matrix.m[0][2];
|
||||
m[1][0] -= matrix.m[1][0]; m[1][1] -= matrix.m[1][1]; m[1][2] -= matrix.m[1][2];
|
||||
m[2][0] -= matrix.m[2][0]; m[2][1] -= matrix.m[2][1]; m[2][2] -= matrix.m[2][2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Overloaded operator for multiplication with a number with assignment
|
||||
Matrix3& operator*=(float nb) {
|
||||
m[0][0] *= nb; m[0][1] *= nb; m[0][2] *= nb;
|
||||
m[1][0] *= nb; m[1][1] *= nb; m[1][2] *= nb;
|
||||
m[2][0] *= nb; m[2][1] *= nb; m[2][2] *= nb;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
419
examples/opengl-framework/src/maths/Matrix4.h
Normal file
419
examples/opengl-framework/src/maths/Matrix4.h
Normal file
|
@ -0,0 +1,419 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef MATRIX4_H
|
||||
#define MATRIX4_H
|
||||
|
||||
// Libraries
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include "Vector3.h"
|
||||
#include "Vector4.h"
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Matrix4
|
||||
// This class represents a 4x4 matrix
|
||||
class Matrix4 {
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Elements of the matrix
|
||||
float m[4][4];
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Matrix4(float m_00=0, float m_01=0, float m_02=0, float m_03=0,
|
||||
float m_10=0, float m_11=0, float m_12=0, float m_13=0,
|
||||
float m_20=0, float m_21=0, float m_22=0, float m_23=0,
|
||||
float m_30=0, float m_31=0, float m_32=0, float m_33=0) {
|
||||
m[0][0] = m_00; m[0][1] = m_01; m[0][2] = m_02; m[0][3] = m_03;
|
||||
m[1][0] = m_10; m[1][1] = m_11; m[1][2] = m_12; m[1][3] = m_13;
|
||||
m[2][0] = m_20; m[2][1] = m_21; m[2][2] = m_22; m[2][3] = m_23;
|
||||
m[3][0] = m_30; m[3][1] = m_31; m[3][2] = m_32; m[3][3] = m_33;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix4(float n[4][4]) {
|
||||
m[0][0]=n[0][0]; m[0][1]=n[0][1]; m[0][2]=n[0][2]; m[0][3]=n[0][3];
|
||||
m[1][0]=n[1][0]; m[1][1]=n[1][1]; m[1][2]=n[1][2]; m[1][3]=n[1][3];
|
||||
m[2][0]=n[2][0]; m[2][1]=n[2][1]; m[2][2]=n[2][2]; m[2][3]=n[2][3];
|
||||
m[3][0]=n[3][0]; m[3][1]=n[3][1]; m[3][2]=n[3][2]; m[3][3]=n[3][3];
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix4(const Vector3& a1, const Vector3& a2, const Vector3& a3) {
|
||||
m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x; m[0][3] = 0.f;
|
||||
m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y; m[1][3] = 0.f;
|
||||
m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z; m[2][3] = 0.f;
|
||||
m[3][0] = 0.f; m[3][1] = 0.f; m[3][2] = 0.f; m[3][3] = 1.f;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix4(const Vector4& a1, const Vector4& a2, const Vector4& a3) {
|
||||
m[0][0] = a1.x; m[0][1] = a2.x; m[0][2] = a3.x; m[0][3] = 0.f;
|
||||
m[1][0] = a1.y; m[1][1] = a2.y; m[1][2] = a3.y; m[1][3] = 0.f;
|
||||
m[2][0] = a1.z; m[2][1] = a2.z; m[2][2] = a3.z; m[2][3] = 0.f;
|
||||
m[3][0] = a1.w; m[3][1] = a2.w; m[3][2] = a3.w; m[3][3] = 1.f;
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Matrix4(const Matrix4& matrix) {
|
||||
|
||||
setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], matrix.m[0][3],
|
||||
matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], matrix.m[1][3],
|
||||
matrix.m[2][0], matrix.m[2][1], matrix.m[2][2], matrix.m[2][3],
|
||||
matrix.m[3][0], matrix.m[3][1], matrix.m[3][2], matrix.m[3][3]);
|
||||
}
|
||||
|
||||
// + operator
|
||||
Matrix4 operator+(const Matrix4 &n) const {
|
||||
return Matrix4(m[0][0]+n.m[0][0], m[0][1]+n.m[0][1], m[0][2]+n.m[0][2], m[0][3]+n.m[0][3],
|
||||
m[1][0]+n.m[1][0], m[1][1]+n.m[1][1], m[1][2]+n.m[1][2], m[1][3]+n.m[1][3],
|
||||
m[2][0]+n.m[2][0], m[2][1]+n.m[2][1], m[2][2]+n.m[2][2], m[2][3]+n.m[2][3],
|
||||
m[3][0]+n.m[3][0], m[3][1]+n.m[3][1], m[3][2]+n.m[3][2], m[3][3]+n.m[3][3]);
|
||||
}
|
||||
|
||||
// += operator
|
||||
Matrix4& operator+=(const Matrix4 &n) {
|
||||
m[0][0]+=n.m[0][0]; m[0][1]+=n.m[0][1]; m[0][2]+=n.m[0][2]; m[0][3]+=n.m[0][3];
|
||||
m[1][0]+=n.m[1][0]; m[1][1]+=n.m[1][1]; m[1][2]+=n.m[1][2]; m[1][3]+=n.m[1][3];
|
||||
m[2][0]+=n.m[2][0]; m[2][1]+=n.m[2][1]; m[2][2]+=n.m[2][2]; m[2][3]+=n.m[2][3];
|
||||
m[3][0]+=n.m[3][0]; m[3][1]+=n.m[3][1]; m[3][2]+=n.m[3][2]; m[3][3]+=n.m[3][3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Matrix4 operator-(const Matrix4 &n) const {
|
||||
return Matrix4(m[0][0]-n.m[0][0], m[0][1]-n.m[0][1], m[0][2]-n.m[0][2], m[0][3]-n.m[0][3],
|
||||
m[1][0]-n.m[1][0], m[1][1]-n.m[1][1], m[1][2]-n.m[1][2], m[1][3]-n.m[1][3],
|
||||
m[2][0]-n.m[2][0], m[2][1]-n.m[2][1], m[2][2]-n.m[2][2], m[2][3]-n.m[2][3],
|
||||
m[3][0]-n.m[3][0], m[3][1]-n.m[3][1], m[3][2]-n.m[3][2], m[3][3]-n.m[3][3]);
|
||||
}
|
||||
|
||||
// -= operator
|
||||
Matrix4& operator-=(const Matrix4 &n) {
|
||||
m[0][0]-=n.m[0][0]; m[0][1]-=n.m[0][1]; m[0][2]-=n.m[0][2]; m[0][3]-=n.m[0][3];
|
||||
m[1][0]-=n.m[1][0]; m[1][1]-=n.m[1][1]; m[1][2]-=n.m[1][2]; m[1][3]-=n.m[1][3];
|
||||
m[2][0]-=n.m[2][0]; m[2][1]-=n.m[2][1]; m[2][2]-=n.m[2][2]; m[2][3]-=n.m[2][3];
|
||||
m[3][0]-=n.m[3][0]; m[3][1]-=n.m[3][1]; m[3][2]-=n.m[3][2]; m[3][3]-=n.m[3][3];
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = operator
|
||||
Matrix4& operator=(const Matrix4& matrix) {
|
||||
if (&matrix != this) {
|
||||
setAllValues(matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], matrix.m[0][3],
|
||||
matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], matrix.m[1][3],
|
||||
matrix.m[2][0], matrix.m[2][1], matrix.m[2][2], matrix.m[2][3],
|
||||
matrix.m[3][0], matrix.m[3][1], matrix.m[3][2], matrix.m[3][3]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// == operator
|
||||
bool operator==(const Matrix4 &n) const {
|
||||
return m[0][0]==n.m[0][0] && m[0][1]==n.m[0][1] && m[0][2]==n.m[0][2] && m[0][3]==n.m[0][3] &&
|
||||
m[1][0]==n.m[1][0] && m[1][1]==n.m[1][1] && m[1][2]==n.m[1][2] && m[1][3]==n.m[1][3] &&
|
||||
m[2][0]==n.m[2][0] && m[2][1]==n.m[2][1] && m[2][2]==n.m[2][2] && m[2][3]==n.m[2][3] &&
|
||||
m[3][0]==n.m[3][0] && m[3][1]==n.m[3][1] && m[3][2]==n.m[3][2] && m[3][3]==n.m[3][3];
|
||||
}
|
||||
|
||||
// * operator
|
||||
Matrix4 operator*(const Matrix4 &n) const {
|
||||
Matrix4 o;
|
||||
for(int i = 0; i < 4; i++) {
|
||||
for(int j = 0; j < 4; j++) {
|
||||
float v = 0;
|
||||
for(int k = 0; k < 4; k++) {
|
||||
v += m[i][k] * n.m[k][j];
|
||||
}
|
||||
o.m[i][j] = v;
|
||||
}
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
// * operator
|
||||
Vector3 operator*(const Vector3 &v) const {
|
||||
Vector3 u =Vector3(m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + m[0][3],
|
||||
m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + m[1][3],
|
||||
m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + m[2][3]);
|
||||
float w = m[3][0]*v.x + m[3][1]*v.y + m[3][2]*v.z + m[3][3];
|
||||
return u/w;
|
||||
}
|
||||
|
||||
// * operator
|
||||
Vector4 operator*(const Vector4 &v) const {
|
||||
Vector4 u = Vector4(m[0][0]*v.x + m[0][1]*v.y + m[0][2]*v.z + v.w*m[0][3],
|
||||
m[1][0]*v.x + m[1][1]*v.y + m[1][2]*v.z + v.w*m[1][3],
|
||||
m[2][0]*v.x + m[2][1]*v.y + m[2][2]*v.z + v.w*m[2][3],
|
||||
m[3][0]*v.x + m[3][1]*v.y + m[3][2]*v.z + v.w*m[3][3]);
|
||||
if(u.w != 0)
|
||||
return u/u.w;
|
||||
else
|
||||
return u;
|
||||
}
|
||||
|
||||
// * operator
|
||||
Matrix4 operator*(float f) const {
|
||||
return Matrix4(m[0][0]*f, m[0][1]*f, m[0][2]*f, m[0][3]*f,
|
||||
m[1][0]*f, m[1][1]*f, m[1][2]*f, m[1][3]*f,
|
||||
m[2][0]*f, m[2][1]*f, m[2][2]*f, m[2][3]*f,
|
||||
m[3][0]*f, m[3][1]*f, m[3][2]*f, m[3][3]*f);
|
||||
}
|
||||
|
||||
// * operator
|
||||
Matrix4 &operator*=(float f) {
|
||||
m[0][0]*=f; m[0][1]*=f; m[0][2]*=f; m[0][3]*=f;
|
||||
m[1][0]*=f; m[1][1]*=f; m[1][2]*=f; m[1][3]*=f;
|
||||
m[2][0]*=f; m[2][1]*=f; m[2][2]*=f; m[2][3]*=f;
|
||||
m[3][0]*=f; m[3][1]*=f; m[3][2]*=f; m[3][3]*=f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// / operator
|
||||
Matrix4 operator/(float f) const {
|
||||
assert(f!=0);
|
||||
return Matrix4(m[0][0]/f, m[0][1]/f, m[0][2]/f, m[0][3]/f,
|
||||
m[1][0]/f, m[1][1]/f, m[1][2]/f, m[1][3]/f,
|
||||
m[2][0]/f, m[2][1]/f, m[2][2]/f, m[2][3]/f,
|
||||
m[3][0]/f, m[3][1]/f, m[3][2]/f, m[3][3]/f);
|
||||
}
|
||||
|
||||
// /= operator
|
||||
Matrix4 &operator/=(float f) {
|
||||
assert(f!=0);
|
||||
m[0][0]/=f; m[0][1]/=f; m[0][2]/=f; m[0][3]/=f;
|
||||
m[1][0]/=f; m[1][1]/=f; m[1][2]/=f; m[1][3]/=f;
|
||||
m[2][0]/=f; m[2][1]/=f; m[2][2]/=f; m[2][3]/=f;
|
||||
m[3][0]/=f; m[3][1]/=f; m[3][2]/=f; m[3][3]/=f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Matrix4 operator-() const {
|
||||
return Matrix4(-m[0][0], -m[0][1], -m[0][2], -m[0][3],
|
||||
-m[1][0], -m[1][1], -m[1][2], -m[1][3],
|
||||
-m[2][0], -m[2][1], -m[2][2], -m[2][3],
|
||||
-m[3][0], -m[3][1], -m[3][2], -m[3][3]);
|
||||
}
|
||||
|
||||
// Return the transpose matrix
|
||||
Matrix4 getTranspose() const {
|
||||
return Matrix4(m[0][0], m[1][0], m[2][0], m[3][0],
|
||||
m[0][1], m[1][1], m[2][1], m[3][1],
|
||||
m[0][2], m[1][2], m[2][2], m[3][2],
|
||||
m[0][3], m[1][3], m[2][3], m[3][3]);
|
||||
}
|
||||
|
||||
// Return the inversed matrix
|
||||
Matrix4 getInverse() const {
|
||||
int indxc[4], indxr[4];
|
||||
int ipiv[4] = { 0, 0, 0, 0 };
|
||||
float minv[4][4];
|
||||
float temp;
|
||||
|
||||
for (int s=0; s<4; s++) {
|
||||
for (int t=0; t<4; t++) {
|
||||
minv[s][t] = m[s][t];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int irow = -1, icol = -1;
|
||||
float big = 0.;
|
||||
// Choose pivot
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (ipiv[j] != 1) {
|
||||
for (int k = 0; k < 4; k++) {
|
||||
if (ipiv[k] == 0) {
|
||||
if (fabs(minv[j][k]) >= big) {
|
||||
big = float(fabs(minv[j][k]));
|
||||
irow = j;
|
||||
icol = k;
|
||||
}
|
||||
}
|
||||
else if (ipiv[k] > 1) {
|
||||
std::cout << "ERROR: Singular matrix in MatrixInvert\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++ipiv[icol];
|
||||
// Swap rows _irow_ and _icol_ for pivot
|
||||
if (irow != icol) {
|
||||
for (int k = 0; k < 4; ++k){
|
||||
temp = minv[irow][k];
|
||||
minv[irow][k] = minv[icol][k];
|
||||
minv[icol][k] = temp;
|
||||
}
|
||||
}
|
||||
indxr[i] = irow;
|
||||
indxc[i] = icol;
|
||||
if (minv[icol][icol] == 0.){
|
||||
std::cout << "Singular matrix in MatrixInvert\n";
|
||||
}
|
||||
// Set $m[icol][icol]$ to one by scaling row _icol_ appropriately
|
||||
float pivinv = 1.f / minv[icol][icol];
|
||||
minv[icol][icol] = 1.f;
|
||||
for (int j = 0; j < 4; j++) {
|
||||
minv[icol][j] *= pivinv;
|
||||
}
|
||||
|
||||
// Subtract this row from others to zero out their columns
|
||||
for (int j = 0; j < 4; j++) {
|
||||
if (j != icol) {
|
||||
float save = minv[j][icol];
|
||||
minv[j][icol] = 0;
|
||||
for (int k = 0; k < 4; k++) {
|
||||
minv[j][k] -= minv[icol][k]*save;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Swap columns to reflect permutation
|
||||
for (int j = 3; j >= 0; j--) {
|
||||
if (indxr[j] != indxc[j]) {
|
||||
for (int k = 0; k < 4; k++){
|
||||
temp = minv[k][indxr[j]];
|
||||
minv[k][indxr[j]] = minv[k][indxc[j]];
|
||||
minv[k][indxc[j]] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Matrix4(minv);
|
||||
}
|
||||
|
||||
// Method to set all the values in the matrix
|
||||
void setAllValues(float a1, float a2, float a3, float a4,
|
||||
float b1, float b2, float b3, float b4,
|
||||
float c1, float c2, float c3, float c4,
|
||||
float d1, float d2, float d3, float d4) {
|
||||
m[0][0] = a1; m[0][1] = a2; m[0][2] = a3, m[0][3] = a4;
|
||||
m[1][0] = b1; m[1][1] = b2; m[1][2] = b3; m[1][3] = b4;
|
||||
m[2][0] = c1; m[2][1] = c2; m[2][2] = c3; m[2][3] = c4;
|
||||
m[3][0] = d1; m[3][1] = d2; m[3][2] = d3; m[3][3] = d4;
|
||||
}
|
||||
|
||||
// Set the matrix to the identity matrix
|
||||
Matrix4 setToIdentity() {
|
||||
m[0][0] = 1.f; m[0][1] = 0.f; m[0][2] = 0.f; m[0][3] = 0.f;
|
||||
m[1][0] = 0.f; m[1][1] = 1.f; m[1][2] = 0.f; m[1][3] = 0.f;
|
||||
m[2][0] = 0.f; m[2][1] = 0.f; m[2][2] = 1.f; m[2][3] = 0.f;
|
||||
m[3][0] = 0.f; m[3][1] = 0.f; m[3][2] = 0.f; m[3][3] = 1.f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Display the matrix
|
||||
void print() const {
|
||||
for (int i=0; i<4; i++) {
|
||||
for (int j=0; j<4; j++) {
|
||||
std::cout << m[i][j];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the pointer to the data array of the matrix
|
||||
float* dataBlock() {
|
||||
return m[0];
|
||||
}
|
||||
|
||||
// Return the constant pointer to the data array of the matrix
|
||||
const float* dataBlock() const {
|
||||
return m[0];
|
||||
}
|
||||
|
||||
// Return a given value from the matrix
|
||||
float getValue(int i, int j) const {
|
||||
assert(i >= 0 && i<4 && j >= 0 && j<4);
|
||||
return m[i][j];
|
||||
}
|
||||
|
||||
// Return the trace of the matrix
|
||||
float getTrace() const {
|
||||
// Compute and return the trace
|
||||
return (m[0][0] + m[1][1] + m[2][2] + m[3][3]);
|
||||
}
|
||||
|
||||
// Return a 4x4 translation matrix
|
||||
static Matrix4 translationMatrix(const Vector3& v);
|
||||
|
||||
// Return a 4x4 rotation matrix
|
||||
static Matrix4 rotationMatrix(const Vector3& axis, float angle);
|
||||
};
|
||||
|
||||
// * operator
|
||||
inline Matrix4 operator*(float f, const Matrix4 & m) {
|
||||
return (m * f);
|
||||
}
|
||||
|
||||
// Return a 4x4 translation matrix
|
||||
inline Matrix4 Matrix4::translationMatrix(const Vector3& v) {
|
||||
return Matrix4(1, 0, 0, v.x,
|
||||
0, 1, 0, v.y,
|
||||
0, 0, 1, v.z,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
// Return a 4x4 rotation matrix
|
||||
inline Matrix4 Matrix4::rotationMatrix(const Vector3& axis, float angle) {
|
||||
|
||||
float cosA = cos(angle);
|
||||
float sinA = sin(angle);
|
||||
Matrix4 rotationMatrix;
|
||||
rotationMatrix.setToIdentity();
|
||||
|
||||
rotationMatrix.m[0][0] = cosA + (1-cosA) * axis.x * axis.x;
|
||||
rotationMatrix.m[0][1] = (1-cosA) * axis.x * axis.y - axis.z * sinA;
|
||||
rotationMatrix.m[0][2] = (1-cosA) * axis.x * axis.z + axis.y * sinA;
|
||||
rotationMatrix.m[0][3] = 0.f;
|
||||
|
||||
rotationMatrix.m[1][0] = (1-cosA) * axis.x * axis.y + axis.z * sinA;
|
||||
rotationMatrix.m[1][1] = cosA + (1-cosA) * axis.y * axis.y;
|
||||
rotationMatrix.m[1][2] = (1-cosA) * axis.y * axis.z - axis.x * sinA;
|
||||
rotationMatrix.m[1][3] = 0.f;
|
||||
|
||||
rotationMatrix.m[2][0] = (1-cosA) * axis.x * axis.z - axis.y * sinA;
|
||||
rotationMatrix.m[2][1] = (1-cosA) * axis.y * axis.z + axis.x * sinA;
|
||||
rotationMatrix.m[2][2] = cosA + (1-cosA) * axis.z * axis.z;
|
||||
rotationMatrix.m[2][3] = 0.f;
|
||||
|
||||
rotationMatrix.m[3][0] = 0.f;
|
||||
rotationMatrix.m[3][1] = 0.f;
|
||||
rotationMatrix.m[3][2] = 0.f;
|
||||
rotationMatrix.m[3][3] = 1.f;
|
||||
|
||||
return rotationMatrix;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //_MATRIX4_H
|
159
examples/opengl-framework/src/maths/Vector2.h
Normal file
159
examples/opengl-framework/src/maths/Vector2.h
Normal file
|
@ -0,0 +1,159 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef VECTOR2_H
|
||||
#define VECTOR2_H
|
||||
|
||||
// Libraries
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Vector2
|
||||
// This class represents a 2D vector.
|
||||
class Vector2 {
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Components of the vector
|
||||
float x, y;
|
||||
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Vector2(float x=0, float y=0) : x(x), y(y) {}
|
||||
|
||||
// Constructor
|
||||
Vector2(const Vector2& vector) : x(vector.x), y(vector.y) {}
|
||||
|
||||
// + operator
|
||||
Vector2 operator+(const Vector2 &v) const {
|
||||
return Vector2(x + v.x, y + v.y);
|
||||
}
|
||||
|
||||
// += operator
|
||||
Vector2& operator+=(const Vector2 &v) {
|
||||
x += v.x; y += v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector2 operator-(const Vector2 &v) const {
|
||||
return Vector2(x - v.x, y - v.y);
|
||||
}
|
||||
|
||||
// -= operator
|
||||
Vector2& operator-=(const Vector2 &v) {
|
||||
x -= v.x; y -= v.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = operator
|
||||
Vector2& operator=(const Vector2& vector) {
|
||||
if (&vector != this) {
|
||||
x = vector.x;
|
||||
y = vector.y;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// == operator
|
||||
bool operator==(const Vector2 &v) const {
|
||||
return x == v.x && y == v.y;
|
||||
}
|
||||
|
||||
// * operator
|
||||
Vector2 operator*(float f) const {
|
||||
return Vector2(f*x, f*y);
|
||||
}
|
||||
|
||||
// *= operator
|
||||
Vector2 &operator*=(float f) {
|
||||
x *= f; y *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// / operator
|
||||
Vector2 operator/(float f) const {
|
||||
assert(f!=0);
|
||||
float inv = 1.f / f;
|
||||
return Vector2(x * inv, y * inv);
|
||||
}
|
||||
|
||||
// /= operator
|
||||
Vector2 &operator/=(float f) {
|
||||
assert(f!=0);
|
||||
float inv = 1.f / f;
|
||||
x *= inv; y *= inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector2 operator-() const {
|
||||
return Vector2(-x, -y);
|
||||
}
|
||||
|
||||
// [] operator
|
||||
float &operator[](int i) {
|
||||
assert(i >= 0 && i <= 1);
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
// Normalize the vector and return it
|
||||
Vector2 normalize() {
|
||||
float l = length();
|
||||
assert(l > 0);
|
||||
x /= l;
|
||||
y /= l;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Clamp the vector values between 0 and 1
|
||||
Vector2 clamp01() {
|
||||
if (x>1.f) x=1.f;
|
||||
else if (x<0.f) x=0.f;
|
||||
if (y>1.f) y=1.f;
|
||||
else if (y<0.f) y=0.f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return the squared length of the vector
|
||||
float lengthSquared() const { return x*x + y*y; }
|
||||
|
||||
// Return the length of the vector
|
||||
float length() const { return sqrt(lengthSquared()); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
203
examples/opengl-framework/src/maths/Vector3.h
Normal file
203
examples/opengl-framework/src/maths/Vector3.h
Normal file
|
@ -0,0 +1,203 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef OPENGLFRAMEWORK_VECTOR3_H
|
||||
#define OPENGLFRAMEWORK_VECTOR3_H
|
||||
|
||||
// Libraries
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Vector3
|
||||
// This class represents a 3D vector.
|
||||
class Vector3 {
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Components of the vector
|
||||
float x, y, z;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Vector3(float x=0, float y=0, float z=0) : x(x), y(y), z(z) {}
|
||||
|
||||
// Constructor
|
||||
Vector3(const Vector3& vector) : x(vector.x), y(vector.y), z(vector.z) {}
|
||||
|
||||
// Constructor
|
||||
~Vector3() {}
|
||||
|
||||
// = operator
|
||||
Vector3& operator=(const Vector3& vector) {
|
||||
if (&vector != this) {
|
||||
x = vector.x;
|
||||
y = vector.y;
|
||||
z = vector.z;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// + operator
|
||||
Vector3 operator+(const Vector3 &v) const {
|
||||
return Vector3(x + v.x, y + v.y, z + v.z);
|
||||
}
|
||||
|
||||
// += operator
|
||||
Vector3& operator+=(const Vector3 &v) {
|
||||
x += v.x; y += v.y; z += v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector3 operator-(const Vector3 &v) const {
|
||||
return Vector3(x - v.x, y - v.y, z - v.z);
|
||||
}
|
||||
|
||||
// -= operator
|
||||
Vector3& operator-=(const Vector3 &v) {
|
||||
x -= v.x; y -= v.y; z -= v.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// == operator
|
||||
bool operator==(const Vector3 &v) const {
|
||||
return x == v.x && y == v.y && z == v.z;
|
||||
}
|
||||
|
||||
// != operator
|
||||
bool operator!=(const Vector3 &v) const {
|
||||
return !( *this == v );
|
||||
}
|
||||
|
||||
// * operator
|
||||
Vector3 operator*(float f) const {
|
||||
return Vector3(f*x, f*y, f*z);
|
||||
}
|
||||
|
||||
// *= operator
|
||||
Vector3 &operator*=(float f) {
|
||||
x *= f; y *= f; z *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// / operator
|
||||
Vector3 operator/(float f) const {
|
||||
assert(f > std::numeric_limits<float>::epsilon() );
|
||||
float inv = 1.f / f;
|
||||
return Vector3(x * inv, y * inv, z * inv);
|
||||
}
|
||||
|
||||
// /= operator
|
||||
Vector3 &operator/=(float f) {
|
||||
assert(f > std::numeric_limits<float>::epsilon());
|
||||
float inv = 1.f / f;
|
||||
x *= inv; y *= inv; z *= inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector3 operator-() const {
|
||||
return Vector3(-x, -y, -z);
|
||||
}
|
||||
|
||||
// [] operator
|
||||
float &operator[](int i) {
|
||||
assert(i >= 0 && i <= 2);
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
case 2: return z;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
// [] operator
|
||||
const float &operator[](int i) const {
|
||||
assert(i >= 0 && i <= 2);
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
case 2: return z;
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
// Cross product operator
|
||||
Vector3 cross(const Vector3 &v) const{
|
||||
return Vector3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
|
||||
}
|
||||
|
||||
// Dot product operator
|
||||
float dot(const Vector3 &v) const{
|
||||
return x * v.x + y * v.y + z * v.z;
|
||||
}
|
||||
|
||||
// Normalize the vector and return it
|
||||
Vector3 normalize() {
|
||||
float l = length();
|
||||
if(l < std::numeric_limits<float>::epsilon() ) {
|
||||
assert(false);
|
||||
}
|
||||
x /= l;
|
||||
y /= l;
|
||||
z /= l;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool isNull() const {
|
||||
return( x == 0. && y == 0. && z == 0. );
|
||||
}
|
||||
|
||||
// Clamp the values between 0 and 1
|
||||
Vector3 clamp01() {
|
||||
if (x>1.f) x=1.f;
|
||||
else if (x<0.f) x=0.f;
|
||||
if (y>1.f) y=1.f;
|
||||
else if (y<0.f) y=0.f;
|
||||
if (z>1.f) z=1.f;
|
||||
else if (z<0.f) z=0.f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return the squared length of the vector
|
||||
float lengthSquared() const { return x*x + y*y + z*z; }
|
||||
|
||||
// Return the length of the vector
|
||||
float length() const { return sqrt(lengthSquared()); }
|
||||
};
|
||||
|
||||
inline Vector3 operator*(float f, const Vector3 & o) {
|
||||
return o*f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
167
examples/opengl-framework/src/maths/Vector4.h
Normal file
167
examples/opengl-framework/src/maths/Vector4.h
Normal file
|
@ -0,0 +1,167 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef VECTOR4_H
|
||||
#define VECTOR4_H
|
||||
|
||||
// Libraries
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace openglframework {
|
||||
|
||||
// Class Vector4
|
||||
// This class represents a 4D vector.
|
||||
class Vector4 {
|
||||
|
||||
public:
|
||||
|
||||
// -------------------- Attributes -------------------- //
|
||||
|
||||
// Components of the vector
|
||||
float x, y, z, w;
|
||||
|
||||
// -------------------- Methods -------------------- //
|
||||
|
||||
// Constructor
|
||||
Vector4(float x=0, float y=0, float z=0, float w=0) : x(x), y(y), z(z), w(w) {}
|
||||
|
||||
// Constructor
|
||||
Vector4(const Vector4& vector) : x(vector.x), y(vector.y), z(vector.z), w(vector.w) {}
|
||||
|
||||
// + operator
|
||||
Vector4 operator+(const Vector4 &v) const {
|
||||
return Vector4(x + v.x, y + v.y, z + v.z, w + v.w);
|
||||
}
|
||||
|
||||
// += operator
|
||||
Vector4& operator+=(const Vector4 &v) {
|
||||
x += v.x; y += v.y; z += v.z; w += v.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector4 operator-(const Vector4 &v) const {
|
||||
return Vector4(x - v.x, y - v.y, z - v.z, w - v.w);
|
||||
}
|
||||
|
||||
// -= operator
|
||||
Vector4& operator-=(const Vector4 &v) {
|
||||
x -= v.x; y -= v.y; z -= v.z, w -=v.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// = operator
|
||||
Vector4& operator=(const Vector4& vector) {
|
||||
if (&vector != this) {
|
||||
x = vector.x;
|
||||
y = vector.y;
|
||||
z = vector.z;
|
||||
w = vector.w;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// == operator
|
||||
bool operator==(const Vector4 &v) const {
|
||||
return x == v.x && y == v.y && z == v.z && w == v.w;
|
||||
}
|
||||
|
||||
// * operator
|
||||
Vector4 operator*(float f) const {
|
||||
return Vector4(f*x, f*y, f*z, f*w);
|
||||
}
|
||||
|
||||
// *= operator
|
||||
Vector4 &operator*=(float f) {
|
||||
x *= f; y *= f; z *= f; w *= f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// / operator
|
||||
Vector4 operator/(float f) const {
|
||||
assert(f!=0);
|
||||
float inv = 1.f / f;
|
||||
return Vector4(x * inv, y * inv, z * inv, w * inv);
|
||||
}
|
||||
|
||||
// /= operator
|
||||
Vector4 &operator/=(float f) {
|
||||
assert(f!=0);
|
||||
float inv = 1.f / f;
|
||||
x *= inv; y *= inv; z *= inv; w *= inv;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// - operator
|
||||
Vector4 operator-() const {
|
||||
return Vector4(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
// [] operator
|
||||
float &operator[](int i) {
|
||||
assert(i >= 0 && i <= 3);
|
||||
switch (i) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
case 2: return z;
|
||||
case 3: return w;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
// Dot product operator
|
||||
float dot(const Vector4 &v) const {
|
||||
return x * v.x + y * v.y + z * v.z + w * v.w;
|
||||
}
|
||||
|
||||
// Multiply two vectors by their components
|
||||
Vector4 componentMul(const Vector4 &v) const {
|
||||
return Vector4(x * v.x, y * v.y, z * v.z, w * v.w);
|
||||
}
|
||||
|
||||
// Clamp the values between 0 and 1
|
||||
Vector4 clamp01() {
|
||||
if (x>1.f) x=1.f;
|
||||
else if (x<0.f) x=0.f;
|
||||
if (y>1.f) y=1.f;
|
||||
else if (y<0.f) y=0.f;
|
||||
if (z>1.f) z=1.f;
|
||||
else if (z<0.f) z=0.f;
|
||||
if (w>1.f) w=1.f;
|
||||
else if (w<0.f) w=0.f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return the squared length of the vector
|
||||
float lengthSquared() const { return x * x + y * y + z * z + w * w; }
|
||||
|
||||
// Return the length of the vector
|
||||
float length() const { return sqrt(lengthSquared()); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //_VECTOR4_H
|
49
examples/opengl-framework/src/openglframework.h
Normal file
49
examples/opengl-framework/src/openglframework.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef OPENGL_FRAMEWORK_H
|
||||
#define OPENGL_FRAMEWORK_H
|
||||
|
||||
// Libraries
|
||||
#include "MeshReaderWriter.h"
|
||||
#include "TextureReaderWriter.h"
|
||||
#include "GlutViewer.h"
|
||||
#include "Camera.h"
|
||||
#include "Light.h"
|
||||
#include "Mesh.h"
|
||||
#include "Shader.h"
|
||||
#include "Texture2D.h"
|
||||
#include "FrameBufferObject.h"
|
||||
#include "VertexBufferObject.h"
|
||||
#include "Shader.h"
|
||||
#include "maths/Color.h"
|
||||
#include "maths/Vector2.h"
|
||||
#include "maths/Vector3.h"
|
||||
#include "maths/Vector4.h"
|
||||
#include "maths/Matrix4.h"
|
||||
#include "maths/Matrix3.h"
|
||||
#include "definitions.h"
|
||||
|
||||
#endif
|
32
examples/opengl-framework/src/shaders/depth.frag
Normal file
32
examples/opengl-framework/src/shaders/depth.frag
Normal file
|
@ -0,0 +1,32 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
void main(void) {
|
||||
|
||||
// Compute the depth of the pixel
|
||||
float depth =
|
||||
|
||||
gl_FragColor = vec4(depth, depth, depth, 1);
|
||||
}
|
36
examples/opengl-framework/src/shaders/depth.vert
Normal file
36
examples/opengl-framework/src/shaders/depth.vert
Normal file
|
@ -0,0 +1,36 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Uniform variables
|
||||
uniform mat4 modelToWorldMatrix; // Model too world coordinates matrix
|
||||
uniform mat4 worldToCameraMatrix; // World to camera coordinates matrix
|
||||
uniform mat4 projectionMatrix; // Projection matrix
|
||||
|
||||
void main(void) {
|
||||
|
||||
// Compute the clip-space vertex coordinates
|
||||
gl_Position = projectionMatrix * worldToCameraMatrix *
|
||||
modelToWorldMatrix * gl_Vertex;
|
||||
}
|
63
examples/opengl-framework/src/shaders/phong.frag
Normal file
63
examples/opengl-framework/src/shaders/phong.frag
Normal file
|
@ -0,0 +1,63 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Uniform variables
|
||||
uniform vec3 cameraWorldPosition; // World position of the camera
|
||||
uniform vec3 lightWorldPosition; // World position of the light
|
||||
uniform vec3 lightAmbientColor; // Lights ambient color
|
||||
uniform vec3 lightDiffuseColor; // Light diffuse color
|
||||
uniform vec3 lightSpecularColor; // Light specular color
|
||||
uniform float shininess; // Shininess
|
||||
uniform sampler2D texture; // Texture
|
||||
uniform bool isTexture; // True if we need to use the texture
|
||||
|
||||
// Varying variables
|
||||
varying vec3 worldPosition; // World position of the vertex
|
||||
varying vec3 worldNormal; // World surface normalWorld
|
||||
varying vec2 texCoords; // Texture coordinates
|
||||
|
||||
void main() {
|
||||
|
||||
// Compute the ambient term
|
||||
vec3 ambient = lightAmbientColor;
|
||||
|
||||
// Get the texture color
|
||||
|
||||
vec3 textureColor = vec3(1);
|
||||
if (isTexture) textureColor = texture2D(texture, texCoords).rgb;
|
||||
|
||||
// Compute the diffuse term
|
||||
vec3 L = normalize(lightWorldPosition - worldPosition);
|
||||
vec3 N = normalize(worldNormal);
|
||||
vec3 diffuse = lightDiffuseColor * max(dot(N, L), 0.0) * textureColor;
|
||||
|
||||
// Compute the specular term
|
||||
vec3 V = normalize(cameraWorldPosition - worldPosition);
|
||||
vec3 H = normalize(V + L);
|
||||
vec3 specular = lightSpecularColor * pow(max(dot(N, H), 0), shininess);
|
||||
|
||||
// Compute the final color
|
||||
gl_FragColor = vec4(ambient + diffuse + specular, 1.0);
|
||||
}
|
51
examples/opengl-framework/src/shaders/phong.vert
Normal file
51
examples/opengl-framework/src/shaders/phong.vert
Normal file
|
@ -0,0 +1,51 @@
|
|||
/********************************************************************************
|
||||
* OpenGL-Framework *
|
||||
* Copyright (c) 2013 Daniel Chappuis *
|
||||
*********************************************************************************
|
||||
* *
|
||||
* This software is provided 'as-is', without any express or implied warranty. *
|
||||
* In no event will the authors be held liable for any damages arising from the *
|
||||
* use of this software. *
|
||||
* *
|
||||
* Permission is granted to anyone to use this software for any purpose, *
|
||||
* including commercial applications, and to alter it and redistribute it *
|
||||
* freely, subject to the following restrictions: *
|
||||
* *
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim *
|
||||
* that you wrote the original software. If you use this software in a *
|
||||
* product, an acknowledgment in the product documentation would be *
|
||||
* appreciated but is not required. *
|
||||
* *
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be *
|
||||
* misrepresented as being the original software. *
|
||||
* *
|
||||
* 3. This notice may not be removed or altered from any source distribution. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
// Uniform variables
|
||||
uniform mat4 modelToWorldMatrix; // Model too world coordinates matrix
|
||||
uniform mat4 worldToCameraMatrix; // World to camera coordinates matrix
|
||||
uniform mat4 projectionMatrix; // Projection matrix
|
||||
|
||||
// Varying variables
|
||||
varying vec3 worldPosition; // World position of the vertex
|
||||
varying vec3 worldNormal; // World surface normalWorld
|
||||
varying vec2 texCoords; // Texture coordinates
|
||||
|
||||
void main() {
|
||||
|
||||
// Compute the vertex position
|
||||
vec4 worldPos = modelToWorldMatrix * gl_Vertex;
|
||||
worldPosition = worldPos.xyz;
|
||||
|
||||
// Compute the world surface normal
|
||||
vec3 bodyNormal = normalize(gl_Normal);
|
||||
worldNormal = (modelToWorldMatrix * vec4(bodyNormal, 0.0)).xyz;
|
||||
|
||||
// Get the texture coordinates
|
||||
texCoords = gl_MultiTexCoord0.xy;
|
||||
|
||||
// Compute the clip-space vertex coordinates
|
||||
gl_Position = projectionMatrix * worldToCameraMatrix * worldPos;
|
||||
}
|
Loading…
Reference in New Issue
Block a user