Qt removed.
parent
44bc0b4f5d
commit
f5e0ca5b05
|
@ -0,0 +1,43 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
project(dust3d)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE sources
|
||||||
|
src/glw_osx.m
|
||||||
|
src/glw_internal.h
|
||||||
|
src/glw_style.h
|
||||||
|
src/glw.c
|
||||||
|
src/glw.h
|
||||||
|
src/dmemory.h
|
||||||
|
src/dmemory.c
|
||||||
|
src/3dstruct.h
|
||||||
|
src/array.h
|
||||||
|
src/array.c
|
||||||
|
src/dict.h
|
||||||
|
src/dict.c
|
||||||
|
src/bmesh.h
|
||||||
|
src/bmesh.c
|
||||||
|
src/matrix.h
|
||||||
|
src/matrix.c
|
||||||
|
src/subdivide.h
|
||||||
|
src/subdivide.c
|
||||||
|
src/vector3d.h
|
||||||
|
src/vector3d.c
|
||||||
|
src/convexhull.h
|
||||||
|
src/convexhull.c
|
||||||
|
src/draw.h
|
||||||
|
src/draw.c
|
||||||
|
src/editor.c
|
||||||
|
)
|
||||||
|
|
||||||
|
IF(APPLE)
|
||||||
|
add_executable(dust3d MACOSX_BUNDLE ${sources})
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
include_directories(${OPENGL_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(dust3d ${OPENGL_LIBRARIES})
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework AppKit -framework Quartz")
|
||||||
|
set_target_properties(dust3d PROPERTIES
|
||||||
|
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/src/Info.plist)
|
||||||
|
install(TARGETS dust3d
|
||||||
|
DESTINATION ".")
|
||||||
|
ENDIF (APPLE)
|
22
README.md
22
README.md
|
@ -10,25 +10,6 @@ I was inspired by Jimmy Gunawan's blogs of monster generation, here is the first
|
||||||
of 3D Articulated Shapes](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.357.7134&rep=rep1&type=pdf)(Authors: Zhongping Ji, Ligang Liu, Yigang Wang). I started to think of monster model generation for game development from years ago, thanks for this paper, Dust3D is achievable now.
|
of 3D Articulated Shapes](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.357.7134&rep=rep1&type=pdf)(Authors: Zhongping Ji, Ligang Liu, Yigang Wang). I started to think of monster model generation for game development from years ago, thanks for this paper, Dust3D is achievable now.
|
||||||
From my initial thought, Dust3D should be a tool like [Makehuman](http://www.makehuman.org), with more versatile features, not only can make human, but also be able to **generate monsters automatically**.
|
From my initial thought, Dust3D should be a tool like [Makehuman](http://www.makehuman.org), with more versatile features, not only can make human, but also be able to **generate monsters automatically**.
|
||||||
|
|
||||||
Build
|
|
||||||
============
|
|
||||||
*Generate Xcode Project*
|
|
||||||
```
|
|
||||||
$ cd build
|
|
||||||
$ qmake -spec macx-xcode
|
|
||||||
```
|
|
||||||
*Generate VC Project*
|
|
||||||
```
|
|
||||||
$ cd build
|
|
||||||
$ qmake -tp vc
|
|
||||||
```
|
|
||||||
*Generate Makefile*
|
|
||||||
```
|
|
||||||
$ cd build
|
|
||||||
$ qmake
|
|
||||||
$ make
|
|
||||||
```
|
|
||||||
|
|
||||||
TODO & Progress
|
TODO & Progress
|
||||||
==============
|
==============
|
||||||
- [x] Drawing Primitives (Dec 15, 2016 ~ Dec 17, 2016)
|
- [x] Drawing Primitives (Dec 15, 2016 ~ Dec 17, 2016)
|
||||||
|
@ -84,6 +65,9 @@ This todo already done in the B-Mesh algorithm implementation.
|
||||||
There are lots of changes to the UI part of Dust3D, though not commit yet because of many things have not been finalize.
|
There are lots of changes to the UI part of Dust3D, though not commit yet because of many things have not been finalize.
|
||||||
I removed the Qt, the counterpart of the build system is CMake, and instead of using Qt based OpenGL windows, I am using my own implemented OpenGL support library. I considered using the most popular [Dear ImGui](https://github.com/ocornut/imgui) library, but I really want remove the C++ from the codebase. It's a good start of the skeleton editor UI!
|
I removed the Qt, the counterpart of the build system is CMake, and instead of using Qt based OpenGL windows, I am using my own implemented OpenGL support library. I considered using the most popular [Dear ImGui](https://github.com/ocornut/imgui) library, but I really want remove the C++ from the codebase. It's a good start of the skeleton editor UI!
|
||||||
<img src="screenshot/dust3d_imgui.png" width="280" height="266">
|
<img src="screenshot/dust3d_imgui.png" width="280" height="266">
|
||||||
|
**Feb 11, 2017:**
|
||||||
|
Qt removed, so C++ removed, but Objective-C imported for just support the OpenGL environment on OSX.
|
||||||
|
<img src="screenshot/dust3d_glw_preview.png" width="278" height="167">
|
||||||
|
|
||||||
- [ ] Render rigid animation
|
- [ ] Render rigid animation
|
||||||
- [ ] png exporter for isometric 2.5D game
|
- [ ] png exporter for isometric 2.5D game
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
TARGET = dust3d
|
|
||||||
TEMPLATE = app
|
|
||||||
|
|
||||||
QT += widgets opengl
|
|
||||||
CONFIG += debug
|
|
||||||
|
|
||||||
VPATH += ../src
|
|
||||||
INCLUDEPATH += ../src
|
|
||||||
|
|
||||||
SOURCES += main.cpp \
|
|
||||||
mainwindow.cpp \
|
|
||||||
render.cpp \
|
|
||||||
vector3d.c \
|
|
||||||
draw.cpp \
|
|
||||||
array.c \
|
|
||||||
bmesh.c \
|
|
||||||
matrix.c \
|
|
||||||
convexhull.c \
|
|
||||||
dict.c \
|
|
||||||
osutil.cpp \
|
|
||||||
subdivide.c \
|
|
||||||
skinnedmesh.c \
|
|
||||||
dmemory.c
|
|
||||||
|
|
||||||
HEADERS += mainwindow.h \
|
|
||||||
render.h \
|
|
||||||
vector3d.h \
|
|
||||||
draw.h \
|
|
||||||
array.h \
|
|
||||||
bmesh.h \
|
|
||||||
matrix.h \
|
|
||||||
convexhull.h \
|
|
||||||
dict.h \
|
|
||||||
3dstruct.h \
|
|
||||||
osutil.h \
|
|
||||||
subdivide.h \
|
|
||||||
skinnedmesh.h \
|
|
||||||
dmemory.h
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string></string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>Copyright © 2017 dust3d. All rights reserved.</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string>NSApplication</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -11,7 +11,6 @@
|
||||||
#include "matrix.h"
|
#include "matrix.h"
|
||||||
#include "convexhull.h"
|
#include "convexhull.h"
|
||||||
#include "subdivide.h"
|
#include "subdivide.h"
|
||||||
#include "draw.h"
|
|
||||||
|
|
||||||
#define BMESH_MAX_PARENT_BALL_DEPTH 1000
|
#define BMESH_MAX_PARENT_BALL_DEPTH 1000
|
||||||
#define BMESH_INTVAL_DIST_DIV 10
|
#define BMESH_INTVAL_DIST_DIV 10
|
||||||
|
@ -547,10 +546,6 @@ static convexHull *createConvexHullForBall(bmesh *bm, int depth,
|
||||||
for (i = 0; i < arrayGetLength(ballPtrArray); ++i) {
|
for (i = 0; i < arrayGetLength(ballPtrArray); ++i) {
|
||||||
bmeshBall *ballItem = *((bmeshBall **)arrayGetItem(ballPtrArray, i));
|
bmeshBall *ballItem = *((bmeshBall **)arrayGetItem(ballPtrArray, i));
|
||||||
ballItem->convexHullCount++;
|
ballItem->convexHullCount++;
|
||||||
drawDebugPrintf("convexHullCount:%d", ballItem->convexHullCount);
|
|
||||||
if (ballItem->convexHullCount == 1) {
|
|
||||||
drawDebugPoint(&ballItem->position, ballItem->index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arrayDestroy(ballPtrArray);
|
arrayDestroy(ballPtrArray);
|
||||||
|
@ -727,7 +722,7 @@ static void bmeshGenerateInbetweenMeshFrom(bmesh *bm, int depth,
|
||||||
bmeshAddWallsBetweenQuadsToModel(bm, &ball->position, ¤tFace,
|
bmeshAddWallsBetweenQuadsToModel(bm, &ball->position, ¤tFace,
|
||||||
&childFace);
|
&childFace);
|
||||||
bmeshAddQuadToModel(bm, &childFace);
|
bmeshAddQuadToModel(bm, &childFace);
|
||||||
drawQuad(&childFace);
|
//drawQuad(&childFace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (1 == ball->convexHullCount && !ball->meshGenerated) {
|
else if (1 == ball->convexHullCount && !ball->meshGenerated) {
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "convexhull.h"
|
#include "convexhull.h"
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
#include "dict.h"
|
#include "dict.h"
|
||||||
#include "draw.h"
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Implement Gift wrapping method which describled in http://dccg.upc.edu/people/vera/wp-content/uploads/2014/11/GA2014-ConvexHulls3D-Roger-Hernando.pdf
|
// Implement Gift wrapping method which describled in http://dccg.upc.edu/people/vera/wp-content/uploads/2014/11/GA2014-ConvexHulls3D-Roger-Hernando.pdf
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
#include <QtGui>
|
|
||||||
#include <QtOpenGL>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <math.h>
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
|
||||||
static GLUquadricObj *quadricId = 0;
|
static GLUquadricObj *quadricId = 0;
|
||||||
|
@ -88,8 +87,6 @@ int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices,
|
||||||
}
|
}
|
||||||
|
|
||||||
int drawGrid(float size, float step) {
|
int drawGrid(float size, float step) {
|
||||||
glDisable(GL_LIGHTING);
|
|
||||||
|
|
||||||
// x z plane
|
// x z plane
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
for (GLfloat i = -size; i <= size; i += step) {
|
for (GLfloat i = -size; i <= size; i += step) {
|
||||||
|
@ -105,8 +102,6 @@ int drawGrid(float size, float step) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
glEnable(GL_LIGHTING);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +110,8 @@ int drawPrintf(int x, int y, const char *fmt, ...) {
|
||||||
char text[1024];
|
char text[1024];
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vsnprintf(text, sizeof(text), fmt, args);
|
vsnprintf(text, sizeof(text), fmt, args);
|
||||||
return drawText(x, y, text);
|
//return drawText(x, y, text);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const float drawDebugColors[][4] = {
|
static const float drawDebugColors[][4] = {
|
|
@ -12,6 +12,10 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265
|
||||||
|
#endif
|
||||||
|
|
||||||
int drawInit(void);
|
int drawInit(void);
|
||||||
int drawSphere(vec3 *origin, float radius, int slices, int stacks);
|
int drawSphere(vec3 *origin, float radius, int slices, int stacks);
|
||||||
void drawTriangle(triangle *poly);
|
void drawTriangle(triangle *poly);
|
||||||
|
|
|
@ -0,0 +1,229 @@
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <OpenGL/glu.h>
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <GL/glu.h>
|
||||||
|
#endif
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "glw.h"
|
||||||
|
#include "glw_style.h"
|
||||||
|
#include "draw.h"
|
||||||
|
#include "bmesh.h"
|
||||||
|
|
||||||
|
#define GEN_ID __LINE__
|
||||||
|
|
||||||
|
#define ED_MODE_EDIT 0
|
||||||
|
#define ED_MODE_ANIMATION 1
|
||||||
|
|
||||||
|
#define ED_BACKGROUND_COLOR 0xe4e2e4
|
||||||
|
|
||||||
|
#define ED_SIDEBAR_WIDTH 400
|
||||||
|
#define ED_SPACING 10
|
||||||
|
|
||||||
|
#define ED_TOPBAR_HEIGHT 100
|
||||||
|
#define ED_TOOLBAR_HEIGHT 50
|
||||||
|
|
||||||
|
#define ED_GL_BACKGROUND_COLOR GLW_BACKGROUND_COLOR
|
||||||
|
|
||||||
|
typedef struct editor {
|
||||||
|
glwWin *win;
|
||||||
|
float cameraAngleX;
|
||||||
|
float cameraAngleY;
|
||||||
|
float cameraDistance;
|
||||||
|
int newImId;
|
||||||
|
int showBoneChecked;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int mode;
|
||||||
|
int glLeft;
|
||||||
|
int glTop;
|
||||||
|
int glWidth;
|
||||||
|
int glHeight;
|
||||||
|
int mouseX;
|
||||||
|
int mouseY;
|
||||||
|
bmesh *bm;
|
||||||
|
} editor;
|
||||||
|
|
||||||
|
#include "../data/bmesh_test_2.h"
|
||||||
|
|
||||||
|
static void display(glwWin *win) {
|
||||||
|
editor *ed = glwGetUserData(win);
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glOrtho(0.0, ed->width, ed->height, 0, -1.0, 1.0);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
{
|
||||||
|
char *list[] = {"Open..", "New..", "Save As..", 0};
|
||||||
|
glwImButtonGroup(win, GEN_ID, 100, 30, 300, list, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char *titles[] = {"Library", "Property", 0};
|
||||||
|
glwImTabBox(win, GEN_ID, ED_SPACING / 2, ED_TOPBAR_HEIGHT, ED_SIDEBAR_WIDTH,
|
||||||
|
ed->height - ED_TOPBAR_HEIGHT - ED_SPACING / 2,
|
||||||
|
titles, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int x = ED_SPACING / 2 + ED_SIDEBAR_WIDTH + ED_SPACING;
|
||||||
|
int y = ED_TOPBAR_HEIGHT;
|
||||||
|
int width = ed->width - ED_SIDEBAR_WIDTH - ED_SPACING / 2 - ED_SPACING - ED_SPACING / 2;
|
||||||
|
int height = ed->height - ED_TOPBAR_HEIGHT - ED_SPACING / 2;
|
||||||
|
char *titles[] = {"Edit View", "Animation View", 0};
|
||||||
|
ed->mode = glwImTabBox(win, GEN_ID,
|
||||||
|
x, y, width, height,
|
||||||
|
titles, ed->mode);
|
||||||
|
if (ED_MODE_EDIT == ed->mode) {
|
||||||
|
int glWinY = glwImNextY(win);
|
||||||
|
int bottomY = y + height - ED_TOOLBAR_HEIGHT;
|
||||||
|
glwImBottomBar(win, GEN_ID, x, bottomY, width, ED_TOOLBAR_HEIGHT);
|
||||||
|
ed->showBoneChecked = glwImCheck(win, GEN_ID, x + ED_SPACING + ED_SPACING,
|
||||||
|
bottomY + (ED_TOOLBAR_HEIGHT - glwImLineHeight(win)) / 2 + 2,
|
||||||
|
"Show Bone",
|
||||||
|
ed->showBoneChecked);
|
||||||
|
|
||||||
|
ed->glLeft = x + 1;
|
||||||
|
ed->glTop = glWinY;
|
||||||
|
ed->glWidth = width - 3;
|
||||||
|
ed->glHeight = bottomY - glWinY;
|
||||||
|
|
||||||
|
if (0 == ed->bm) {
|
||||||
|
bmeshBall ball;
|
||||||
|
bmeshBone bone;
|
||||||
|
unsigned int i;
|
||||||
|
ed->bm = bmeshCreate();
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(bmeshTestBalls) / sizeof(bmeshTestBalls[0]); ++i) {
|
||||||
|
memset(&ball, 0, sizeof(ball));
|
||||||
|
ball.position.x = bmeshTestBalls[i][1];
|
||||||
|
ball.position.y = bmeshTestBalls[i][2];
|
||||||
|
ball.position.z = bmeshTestBalls[i][3];
|
||||||
|
ball.radius = bmeshTestBalls[i][4];
|
||||||
|
ball.type = bmeshTestBalls[i][5];
|
||||||
|
bmeshAddBall(ed->bm, &ball);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(bmeshTestBones) / sizeof(bmeshTestBones[0]); ++i) {
|
||||||
|
memset(&bone, 0, sizeof(bone));
|
||||||
|
bone.firstBallIndex = bmeshTestBones[i][0];
|
||||||
|
bone.secondBallIndex = bmeshTestBones[i][1];
|
||||||
|
bmeshAddBone(ed->bm, &bone);
|
||||||
|
}
|
||||||
|
|
||||||
|
bmeshGenerate(ed->bm);
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
glScissor(ed->glLeft, ED_SPACING / 2 + ED_TOOLBAR_HEIGHT + 1,
|
||||||
|
ed->glWidth, ed->glHeight);
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(x + 1, glWinY, 0);
|
||||||
|
|
||||||
|
glColor3f(glwR(ED_GL_BACKGROUND_COLOR),
|
||||||
|
glwG(ED_GL_BACKGROUND_COLOR),
|
||||||
|
glwB(ED_GL_BACKGROUND_COLOR));
|
||||||
|
glRecti(0, 0, ed->glWidth, ed->glHeight);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
gluPerspective(60.0f, (float)ed->glWidth / ed->glHeight, 1, 1000);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(0, 0, -ed->cameraDistance);
|
||||||
|
glRotatef(ed->cameraAngleX, 1, 0, 0);
|
||||||
|
glRotatef(ed->cameraAngleY, 0, 1, 0);
|
||||||
|
|
||||||
|
drawGrid(10, 1);
|
||||||
|
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
bmeshDraw(ed->bm);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reshape(glwWin *win, int width, int height) {
|
||||||
|
editor *ed = glwGetUserData(win);
|
||||||
|
|
||||||
|
glShadeModel(GL_SMOOTH);
|
||||||
|
glEnable(GL_LIGHT0);
|
||||||
|
|
||||||
|
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||||
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
|
|
||||||
|
ed->width = width;
|
||||||
|
ed->height = height;
|
||||||
|
|
||||||
|
glEnable(GL_LINE_SMOOTH);
|
||||||
|
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glEnable(GL_ALPHA_TEST);
|
||||||
|
//glDisable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
|
glClearColor(glwR(ED_BACKGROUND_COLOR),
|
||||||
|
glwG(ED_BACKGROUND_COLOR),
|
||||||
|
glwB(ED_BACKGROUND_COLOR), 1);
|
||||||
|
|
||||||
|
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mouse(glwWin *win, int button, int state,
|
||||||
|
int x, int y){
|
||||||
|
editor *ed = glwGetUserData(win);
|
||||||
|
if (!glwPointTest(x, y, ed->glLeft, ed->glTop,
|
||||||
|
ed->glWidth, ed->glHeight, 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (GLW_DOWN == state) {
|
||||||
|
ed->mouseX = x;
|
||||||
|
ed->mouseY = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void motion(glwWin *win, int x, int y) {
|
||||||
|
editor *ed = glwGetUserData(win);
|
||||||
|
if (!glwPointTest(x, y, ed->glLeft, ed->glTop,
|
||||||
|
ed->glWidth, ed->glHeight, 0)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ed->cameraAngleY += (x - ed->mouseX);
|
||||||
|
ed->cameraAngleX += (y - ed->mouseY);
|
||||||
|
ed->mouseX = x;
|
||||||
|
ed->mouseY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
editor ed;
|
||||||
|
glwInit();
|
||||||
|
memset(&ed, 0, sizeof(ed));
|
||||||
|
ed.cameraAngleX = 30;
|
||||||
|
ed.cameraAngleY = -312;
|
||||||
|
ed.cameraDistance = 14.4;
|
||||||
|
ed.win = glwCreateWindow(0, 0, 0, 0);
|
||||||
|
glwSetUserData(ed.win, &ed);
|
||||||
|
glwReshapeFunc(ed.win, reshape);
|
||||||
|
glwDisplayFunc(ed.win, display);
|
||||||
|
glwMouseFunc(ed.win, mouse);
|
||||||
|
glwMotionFunc(ed.win, motion);
|
||||||
|
glwMainLoop();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,690 @@
|
||||||
|
#include <OpenGL/gl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "glw_internal.h"
|
||||||
|
#include "glw_style.h"
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void glwDrawSystemText(glwWin *win, int x, int y, char *text) {
|
||||||
|
int vleft, vwidth;
|
||||||
|
float tleft, twidth;
|
||||||
|
glwSystemFontTexture *systemFontTexture = glwGetSystemFontTexture(win);
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, systemFontTexture->texId);
|
||||||
|
for (vleft = 0; *text; vleft += vwidth, text++) {
|
||||||
|
int idx = (*text) - GLW_SYSTEM_FONT_BEGIN_CHAR;
|
||||||
|
if (idx < 0 || idx > GLW_SYSTEM_FONT_CHAR_NUM) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tleft = (float)systemFontTexture->lefts[idx] /
|
||||||
|
systemFontTexture->size.width;
|
||||||
|
vwidth = systemFontTexture->widths[idx];
|
||||||
|
twidth = (float)vwidth / systemFontTexture->originSize.width;
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2f(tleft, 0);
|
||||||
|
glVertex2i(x + vleft, y);
|
||||||
|
|
||||||
|
glTexCoord2f(tleft + twidth, 0);
|
||||||
|
glVertex2i(x + vleft + vwidth, y);
|
||||||
|
|
||||||
|
glTexCoord2f(tleft + twidth, 1);
|
||||||
|
glVertex2i(x + vleft + vwidth, y + systemFontTexture->originSize.height);
|
||||||
|
|
||||||
|
glTexCoord2f(tleft, 1);
|
||||||
|
glVertex2i(x + vleft, y + systemFontTexture->originSize.height);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwMouseEvent(glwWin *win, int button, int state, int x, int y) {
|
||||||
|
glwImGui *imGUI = glwGetImGUI(win);
|
||||||
|
imGUI->mouseButton = button;
|
||||||
|
imGUI->mouseState = state;
|
||||||
|
imGUI->mouseX = x;
|
||||||
|
imGUI->mouseY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwPointTest(int x, int y, int left, int top, int width, int height,
|
||||||
|
int allowOffset) {
|
||||||
|
int right = left + width - 1 + allowOffset;
|
||||||
|
int bottom = top + height - 1 + allowOffset;
|
||||||
|
left -= allowOffset;
|
||||||
|
top -= allowOffset;
|
||||||
|
return x >= left && x <= right && y >= top && y <= bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwInitSystemFontTexture(glwWin *win) {
|
||||||
|
char asciiTable[GLW_SYSTEM_FONT_CHAR_NUM + 1];
|
||||||
|
int i;
|
||||||
|
GLuint texture = 0;
|
||||||
|
glwFont *font;
|
||||||
|
int pixelsWide = 0;
|
||||||
|
int pixelsHigh = 0;
|
||||||
|
float scaleX, scaleY;
|
||||||
|
glwSystemFontTexture *systemFontTexture = glwGetSystemFontTexture(win);
|
||||||
|
|
||||||
|
for (i = 0; i <= GLW_SYSTEM_FONT_CHAR_NUM; ++i) {
|
||||||
|
asciiTable[i] = GLW_SYSTEM_FONT_BEGIN_CHAR + i;
|
||||||
|
}
|
||||||
|
asciiTable[GLW_SYSTEM_FONT_CHAR_NUM] = '\0';
|
||||||
|
|
||||||
|
font = glwCreateFont(GLW_SYSTEM_FONT_NAME, GLW_SYSTEM_FONT_WEIGHT,
|
||||||
|
GLW_SYSTEM_FONT_SIZE, 0);
|
||||||
|
systemFontTexture->lefts[0] = 0;
|
||||||
|
systemFontTexture->size.width = 0;
|
||||||
|
systemFontTexture->size.height = 0;
|
||||||
|
for (i = 0; i < GLW_SYSTEM_FONT_CHAR_NUM; ++i) {
|
||||||
|
char ch[2] = {asciiTable[i], '\0'};
|
||||||
|
glwSize chSize = glwMeasureText(ch, font);
|
||||||
|
if (chSize.height > systemFontTexture->size.height) {
|
||||||
|
systemFontTexture->size.height = chSize.height;
|
||||||
|
}
|
||||||
|
systemFontTexture->size.width += chSize.width;
|
||||||
|
systemFontTexture->widths[i] = chSize.width;
|
||||||
|
if (i > 0) {
|
||||||
|
systemFontTexture->lefts[i] = (float)(systemFontTexture->lefts[i - 1] +
|
||||||
|
systemFontTexture->widths[i - 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
systemFontTexture->originSize = systemFontTexture->size;
|
||||||
|
for (i = 0; i < GLW_SYSTEM_FONT_CHAR_NUM; ++i) {
|
||||||
|
char ch[2] = {asciiTable[i], '\0'};
|
||||||
|
glwSize chSize = {systemFontTexture->widths[i],
|
||||||
|
systemFontTexture->originSize.height};
|
||||||
|
unsigned char *rgba = glwRenderTextToRGBA(ch, font, chSize,
|
||||||
|
&pixelsWide, &pixelsHigh);
|
||||||
|
if (0 == i) {
|
||||||
|
scaleX = (float)pixelsWide / chSize.width;
|
||||||
|
scaleY = (float)pixelsHigh / chSize.height;
|
||||||
|
systemFontTexture->size.width *= scaleX;
|
||||||
|
systemFontTexture->size.height *= scaleY;
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glGenTextures(1, &texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, 4,
|
||||||
|
(GLsizei)(systemFontTexture->size.width),
|
||||||
|
(GLsizei)(systemFontTexture->size.height), 0,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
}
|
||||||
|
systemFontTexture->lefts[i] *= scaleX;
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||||
|
systemFontTexture->lefts[i], 0,
|
||||||
|
(GLsizei)pixelsWide,
|
||||||
|
(GLsizei)pixelsHigh,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, rgba);
|
||||||
|
free(rgba);
|
||||||
|
}
|
||||||
|
systemFontTexture->texId = (int)texture;
|
||||||
|
glwDestroyFont(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
static glwVec2 glwRoundedCorners[GLW_SMALL_ROUNDED_CORNER_SLICES] = {{0}};
|
||||||
|
|
||||||
|
static void createRoundedCorners(glwVec2 *arr, int num) {
|
||||||
|
float slice = M_PI / 2 / num;
|
||||||
|
int i;
|
||||||
|
float a = 0;
|
||||||
|
for (i = 0; i < num; a += slice, ++i) {
|
||||||
|
arr[i].x = cosf(a);
|
||||||
|
arr[i].y = sinf(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwInitPrimitives(void) {
|
||||||
|
createRoundedCorners(glwRoundedCorners, GLW_SMALL_ROUNDED_CORNER_SLICES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void glwDrawRightTopVertexs(float left, float top, float right,
|
||||||
|
float bottom, float radius) {
|
||||||
|
int i;
|
||||||
|
for (i = GLW_SMALL_ROUNDED_CORNER_SLICES - 1; i >= 0; --i) {
|
||||||
|
glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
|
||||||
|
top + radius - radius * glwRoundedCorners[i].y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void glwDrawRightBottomVertexs(float left, float top, float right,
|
||||||
|
float bottom, float radius) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < GLW_SMALL_ROUNDED_CORNER_SLICES; ++i) {
|
||||||
|
glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
|
||||||
|
bottom - radius + radius * glwRoundedCorners[i].y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void glwDrawLeftBottomVertexs(float left, float top, float right,
|
||||||
|
float bottom, float radius) {
|
||||||
|
int i;
|
||||||
|
for (i = GLW_SMALL_ROUNDED_CORNER_SLICES - 1; i >= 0; --i) {
|
||||||
|
glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
|
||||||
|
bottom - radius + radius * glwRoundedCorners[i].y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void glwDrawLeftTopVertexs(float left, float top, float right,
|
||||||
|
float bottom, float radius) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < GLW_SMALL_ROUNDED_CORNER_SLICES; ++i) {
|
||||||
|
glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
|
||||||
|
top + radius - radius * glwRoundedCorners[i].y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawCheckSymbol(int x, int y, int width, int height,
|
||||||
|
unsigned int color) {
|
||||||
|
glColor3f(glwR(color), glwG(color), glwB(color));
|
||||||
|
glLineWidth(2);
|
||||||
|
glBegin(GL_LINE_STRIP);
|
||||||
|
glVertex2f(x + width * 0.15, y + height * 0.3);
|
||||||
|
glVertex2f(x + width * 0.45, y + height * 0.65);
|
||||||
|
glVertex2f(x + width * 1.05, y - height * 0.05);
|
||||||
|
glEnd();
|
||||||
|
glLineWidth(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawDropdownArrow(int x, int y, int width, int height,
|
||||||
|
unsigned int color) {
|
||||||
|
glColor3f(glwR(color), glwG(color), glwB(color));
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
glVertex2f(x, y);
|
||||||
|
glVertex2f(x + width, y);
|
||||||
|
glVertex2f(x + width * 0.5, y + height);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawVLine(int x, int y, int width, int height,
|
||||||
|
unsigned int color) {
|
||||||
|
glColor3f(glwR(color), glwG(color), glwB(color));
|
||||||
|
glLineWidth(width);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex2f(x, y);
|
||||||
|
glVertex2f(x, y + height - 1);
|
||||||
|
glEnd();
|
||||||
|
glLineWidth(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawHLine(int x, int y, int width, int height,
|
||||||
|
unsigned int color) {
|
||||||
|
glColor3f(glwR(color), glwG(color), glwB(color));
|
||||||
|
glLineWidth(height);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex2f(x, y);
|
||||||
|
glVertex2f(x + width - 1, y);
|
||||||
|
glEnd();
|
||||||
|
glLineWidth(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawRoundedRectBorder(float x, float y, float width, float height,
|
||||||
|
float radius, unsigned int color) {
|
||||||
|
float left = x;
|
||||||
|
float top = y;
|
||||||
|
float bottom = y + height - 1;
|
||||||
|
float right = x + width - 1;
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glColor3f(glwR(color), glwG(color), glwB(color));
|
||||||
|
glBegin(GL_LINE_LOOP);
|
||||||
|
glVertex2f(left, top + radius);
|
||||||
|
glwDrawLeftTopVertexs(left, top, right, bottom, radius);
|
||||||
|
glVertex2f(left + radius, top);
|
||||||
|
|
||||||
|
glVertex2f(right - radius, top);
|
||||||
|
glwDrawRightTopVertexs(left, top, right, bottom, radius);
|
||||||
|
glVertex2f(right, top + radius);
|
||||||
|
|
||||||
|
glVertex2f(right, bottom - radius);
|
||||||
|
glwDrawRightBottomVertexs(left, top, right, bottom, radius);
|
||||||
|
glVertex2f(right - radius, bottom);
|
||||||
|
|
||||||
|
glVertex2f(left + radius, bottom);
|
||||||
|
glwDrawLeftBottomVertexs(left, top, right, bottom, radius);
|
||||||
|
glVertex2f(left, bottom - radius);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawTopRoundedRectBorder(float x, float y, float width, float height,
|
||||||
|
float radius, unsigned int color) {
|
||||||
|
float left = x;
|
||||||
|
float top = y;
|
||||||
|
float bottom = y + height - 1;
|
||||||
|
float right = x + width - 1;
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glColor3f(glwR(color), glwG(color), glwB(color));
|
||||||
|
glBegin(GL_LINE_LOOP);
|
||||||
|
glVertex2f(left, top + radius);
|
||||||
|
glwDrawLeftTopVertexs(left, top, right, bottom, radius);
|
||||||
|
glVertex2f(left + radius, top);
|
||||||
|
|
||||||
|
glVertex2f(right - radius, top);
|
||||||
|
glwDrawRightTopVertexs(left, top, right, bottom, radius);
|
||||||
|
glVertex2f(right, top + radius);
|
||||||
|
|
||||||
|
glVertex2f(right, bottom);
|
||||||
|
glVertex2f(left, bottom);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawLeftRoundedRectGradientFill(float x, float y,
|
||||||
|
float width, float height,
|
||||||
|
float radius, unsigned int topColor, unsigned int bottomColor) {
|
||||||
|
float left = x;
|
||||||
|
float top = y;
|
||||||
|
float bottom = y + height - 1;
|
||||||
|
float right = x + width - 1;
|
||||||
|
int i;
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glBegin(GL_QUAD_STRIP);
|
||||||
|
for (i = 0; i < GLW_SMALL_ROUNDED_CORNER_SLICES; ++i) {
|
||||||
|
glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
|
||||||
|
glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
|
||||||
|
bottom - radius + radius * glwRoundedCorners[i].y);
|
||||||
|
glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
|
||||||
|
glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
|
||||||
|
top + radius - radius * glwRoundedCorners[i].y);
|
||||||
|
}
|
||||||
|
glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
|
||||||
|
glVertex2f(right, bottom);
|
||||||
|
glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
|
||||||
|
glVertex2f(right, top);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawTopRoundedRectGradientFill(float x, float y,
|
||||||
|
float width, float height,
|
||||||
|
float radius, unsigned int topColor, unsigned int bottomColor) {
|
||||||
|
float left = x;
|
||||||
|
float top = y;
|
||||||
|
float bottom = y + height - 1;
|
||||||
|
float right = x + width - 1;
|
||||||
|
int i;
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glBegin(GL_QUAD_STRIP);
|
||||||
|
for (i = 0; i < GLW_SMALL_ROUNDED_CORNER_SLICES; ++i) {
|
||||||
|
glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
|
||||||
|
glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
|
||||||
|
bottom);
|
||||||
|
glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
|
||||||
|
glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
|
||||||
|
top + radius - radius * glwRoundedCorners[i].y);
|
||||||
|
}
|
||||||
|
for (i = GLW_SMALL_ROUNDED_CORNER_SLICES - 1; i >= 0; --i) {
|
||||||
|
glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
|
||||||
|
glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
|
||||||
|
bottom);
|
||||||
|
glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
|
||||||
|
glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
|
||||||
|
top + radius - radius * glwRoundedCorners[i].y);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawRectGradientFill(float x, float y,
|
||||||
|
float width, float height,
|
||||||
|
unsigned int topColor, unsigned int bottomColor) {
|
||||||
|
float left = x;
|
||||||
|
float top = y;
|
||||||
|
float bottom = y + height - 1;
|
||||||
|
float right = x + width - 1;
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glBegin(GL_QUAD_STRIP);
|
||||||
|
glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
|
||||||
|
glVertex2f(left, bottom);
|
||||||
|
glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
|
||||||
|
glVertex2f(left, top);
|
||||||
|
glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
|
||||||
|
glVertex2f(right, bottom);
|
||||||
|
glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
|
||||||
|
glVertex2f(right, top);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawRightRoundedRectGradientFill(float x, float y,
|
||||||
|
float width, float height,
|
||||||
|
float radius, unsigned int topColor, unsigned int bottomColor) {
|
||||||
|
float left = x;
|
||||||
|
float top = y;
|
||||||
|
float bottom = y + height - 1;
|
||||||
|
float right = x + width - 1;
|
||||||
|
int i;
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glBegin(GL_QUAD_STRIP);
|
||||||
|
glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
|
||||||
|
glVertex2f(left, bottom);
|
||||||
|
glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
|
||||||
|
glVertex2f(left, top);
|
||||||
|
for (i = GLW_SMALL_ROUNDED_CORNER_SLICES - 1; i >= 0; --i) {
|
||||||
|
glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
|
||||||
|
glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
|
||||||
|
bottom - radius + radius * glwRoundedCorners[i].y);
|
||||||
|
glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
|
||||||
|
glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
|
||||||
|
top + radius - radius * glwRoundedCorners[i].y);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawRoundedRectGradientFill(float x, float y, float width, float height,
|
||||||
|
float radius, unsigned int topColor, unsigned int bottomColor) {
|
||||||
|
float left = x;
|
||||||
|
float top = y;
|
||||||
|
float bottom = y + height - 1;
|
||||||
|
float right = x + width - 1;
|
||||||
|
int i;
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glBegin(GL_QUAD_STRIP);
|
||||||
|
for (i = 0; i < GLW_SMALL_ROUNDED_CORNER_SLICES; ++i) {
|
||||||
|
glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
|
||||||
|
glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
|
||||||
|
bottom - radius + radius * glwRoundedCorners[i].y);
|
||||||
|
glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
|
||||||
|
glVertex2f(left + radius - radius * glwRoundedCorners[i].x,
|
||||||
|
top + radius - radius * glwRoundedCorners[i].y);
|
||||||
|
}
|
||||||
|
for (i = GLW_SMALL_ROUNDED_CORNER_SLICES - 1; i >= 0; --i) {
|
||||||
|
glColor3f(glwR(bottomColor), glwG(bottomColor), glwB(bottomColor));
|
||||||
|
glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
|
||||||
|
bottom - radius + radius * glwRoundedCorners[i].y);
|
||||||
|
glColor3f(glwR(topColor), glwG(topColor), glwB(topColor));
|
||||||
|
glVertex2f(right - radius + radius * glwRoundedCorners[i].x,
|
||||||
|
top + radius - radius * glwRoundedCorners[i].y);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDrawButtonBackground(float x, float y, float width, float height,
|
||||||
|
glwCtrlState state) {
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case GLW_CTRL_STATE_PRESS:
|
||||||
|
glwDrawRoundedRectGradientFill(x, y, width, height,
|
||||||
|
GLW_BUTTON_CORNER_RADIUS,
|
||||||
|
GLW_FILL_GRADIENT_COLOR_1_H, GLW_FILL_GRADIENT_COLOR_2_H);
|
||||||
|
break;
|
||||||
|
case GLW_CTRL_STATE_NORMAL:
|
||||||
|
default:
|
||||||
|
glwDrawRoundedRectGradientFill(x, y, width, height,
|
||||||
|
GLW_BUTTON_CORNER_RADIUS,
|
||||||
|
GLW_FILL_GRADIENT_COLOR_1, GLW_FILL_GRADIENT_COLOR_2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
glwDrawRoundedRectBorder(x, y, width, height,
|
||||||
|
GLW_BUTTON_CORNER_RADIUS, GLW_BORDER_COLOR_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
glwSize glwMeasureSystemText(glwWin *win, char *text) {
|
||||||
|
glwSystemFontTexture *systemFontTexture = glwGetSystemFontTexture(win);
|
||||||
|
glwSize size = {0, systemFontTexture->originSize.height};
|
||||||
|
for (; *text; text++) {
|
||||||
|
int idx = (*text) - GLW_SYSTEM_FONT_BEGIN_CHAR;
|
||||||
|
if (idx < 0 || idx > GLW_SYSTEM_FONT_CHAR_NUM) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
size.width += systemFontTexture->widths[idx];
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void glwImGUIActiveIdCheck(glwImGui *imGUI, int id, int x, int y,
|
||||||
|
int width, int height) {
|
||||||
|
if (GLW_DOWN == imGUI->mouseState) {
|
||||||
|
if (!imGUI->activeId) {
|
||||||
|
int hit = glwPointTest(imGUI->mouseX, imGUI->mouseY, x, y,
|
||||||
|
width, height, 0);
|
||||||
|
if (hit) {
|
||||||
|
imGUI->activeId = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (GLW_UP == imGUI->mouseState) {
|
||||||
|
if (imGUI->activeId == id) {
|
||||||
|
imGUI->activeId = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwImButton(glwWin *win, int id, int x, int y, char *text) {
|
||||||
|
glwImGui *imGUI = glwGetImGUI(win);
|
||||||
|
glwSize textSize = glwMeasureSystemText(win, text);
|
||||||
|
int width = textSize.width * (1 + GLW_HOR_AUTO_MARGIN * 2);
|
||||||
|
int height = textSize.height * (1 + GLW_VER_AUTO_MARGIN * 2);
|
||||||
|
glwImGUIActiveIdCheck(imGUI, id, x, y, width, height);
|
||||||
|
glwDrawButtonBackground(x, y, width, height,
|
||||||
|
imGUI->activeId == id ? GLW_CTRL_STATE_PRESS : GLW_CTRL_STATE_NORMAL);
|
||||||
|
glwDrawSystemText(win, x + textSize.width * GLW_HOR_AUTO_MARGIN,
|
||||||
|
y + textSize.height * GLW_VER_AUTO_MARGIN,
|
||||||
|
text);
|
||||||
|
imGUI->nextX = x + width;
|
||||||
|
imGUI->nextY = y;
|
||||||
|
return imGUI->activeId == id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwImDropdownBox(glwWin *win, int id, int x, int y, char *text) {
|
||||||
|
glwImGui *imGUI = glwGetImGUI(win);
|
||||||
|
glwSize textSize = glwMeasureSystemText(win, text);
|
||||||
|
int arrowHeight = textSize.height * 0.3;
|
||||||
|
int arrowWidth = arrowHeight * 2;
|
||||||
|
int width = textSize.width * (1 + GLW_HOR_AUTO_MARGIN * 2) + arrowWidth * 3;
|
||||||
|
int height = textSize.height * (1 + GLW_VER_AUTO_MARGIN * 2);
|
||||||
|
glwImGUIActiveIdCheck(imGUI, id, x, y, width, height);
|
||||||
|
glwDrawButtonBackground(x, y, width, height,
|
||||||
|
imGUI->activeId == id ? GLW_CTRL_STATE_PRESS : GLW_CTRL_STATE_NORMAL);
|
||||||
|
glwDrawSystemText(win, x + textSize.width * (GLW_HOR_AUTO_MARGIN),
|
||||||
|
y + textSize.height * (GLW_VER_AUTO_MARGIN),
|
||||||
|
text);
|
||||||
|
glwDrawDropdownArrow(x + width - textSize.width * GLW_HOR_AUTO_MARGIN -
|
||||||
|
arrowWidth,
|
||||||
|
y + (height - arrowHeight) / 2, arrowWidth, arrowHeight, 0);
|
||||||
|
imGUI->nextX = x + width;
|
||||||
|
imGUI->nextY = y;
|
||||||
|
return imGUI->activeId == id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwImCheck(glwWin *win, int id, int x, int y, char *text, int checked) {
|
||||||
|
glwImGui *imGUI = glwGetImGUI(win);
|
||||||
|
glwSize textSize = glwMeasureSystemText(win, text);
|
||||||
|
int height = textSize.height;
|
||||||
|
int boxWidth = height;
|
||||||
|
int width = boxWidth + textSize.height * (1 + GLW_HOR_AUTO_MARGIN * 2) +
|
||||||
|
textSize.width;
|
||||||
|
int oldActiveId = imGUI->activeId;
|
||||||
|
glwImGUIActiveIdCheck(imGUI, id, x, y, width, height);
|
||||||
|
glwDrawButtonBackground(x, y, boxWidth, height,
|
||||||
|
(imGUI->activeId == id || checked) ?
|
||||||
|
GLW_CTRL_STATE_PRESS : GLW_CTRL_STATE_NORMAL);
|
||||||
|
glwDrawSystemText(win, x + textSize.height * GLW_HOR_AUTO_MARGIN + boxWidth,
|
||||||
|
y, text);
|
||||||
|
if (checked) {
|
||||||
|
glwDrawCheckSymbol(x, y, boxWidth, height, GLW_CHECK_COLOR);
|
||||||
|
}
|
||||||
|
imGUI->nextX = x + width;
|
||||||
|
imGUI->nextY = y;
|
||||||
|
return (imGUI->activeId == id && oldActiveId != id) ? !checked : checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int glwCalcListMaxWidth(glwWin *win, char **list, int *height,
|
||||||
|
int *len) {
|
||||||
|
int i;
|
||||||
|
int itemWidth = 0;
|
||||||
|
int maxItemWidth = 0;
|
||||||
|
|
||||||
|
for (i = 0; list[i]; ++i) {
|
||||||
|
glwSize textSize = glwMeasureSystemText(win, list[i]);
|
||||||
|
itemWidth = textSize.width * (1 + GLW_HOR_AUTO_MARGIN * 2);
|
||||||
|
if (itemWidth > maxItemWidth) {
|
||||||
|
maxItemWidth = itemWidth;
|
||||||
|
}
|
||||||
|
if (height && !(*height)) {
|
||||||
|
*height = textSize.height * (1 + GLW_VER_AUTO_MARGIN * 2);
|
||||||
|
}
|
||||||
|
if (len) {
|
||||||
|
++(*len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxItemWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwImButtonGroup(glwWin *win, int id, int x, int y, int parentWidth,
|
||||||
|
char **list, int sel) {
|
||||||
|
glwImGui *imGUI = glwGetImGUI(win);
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
int left = 0;
|
||||||
|
int i;
|
||||||
|
int listLen = 0;
|
||||||
|
int offset;
|
||||||
|
int maxItemWidth = 0;
|
||||||
|
maxItemWidth = glwCalcListMaxWidth(win, list, &height, &listLen);
|
||||||
|
width = maxItemWidth * listLen;
|
||||||
|
left = listLen > 1 ? x + (parentWidth - width) / 2 :
|
||||||
|
x + maxItemWidth * GLW_HOR_AUTO_MARGIN;
|
||||||
|
glwImGUIActiveIdCheck(imGUI, id, left, y, width, height);
|
||||||
|
glwDrawRoundedRectGradientFill(left, y, width, height,
|
||||||
|
GLW_BUTTON_CORNER_RADIUS,
|
||||||
|
GLW_FILL_GRADIENT_COLOR_1, GLW_FILL_GRADIENT_COLOR_2);
|
||||||
|
for (i = 0, offset = left; list[i]; ++i) {
|
||||||
|
glwSize textSize = glwMeasureSystemText(win, list[i]);
|
||||||
|
if (imGUI->activeId == id) {
|
||||||
|
int hit = glwPointTest(imGUI->mouseX, imGUI->mouseY, offset, y,
|
||||||
|
maxItemWidth, height, 0);
|
||||||
|
if (hit) {
|
||||||
|
sel = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sel == i) {
|
||||||
|
if (1 == listLen) {
|
||||||
|
glwDrawRoundedRectGradientFill(left, y, width, height,
|
||||||
|
GLW_BUTTON_CORNER_RADIUS,
|
||||||
|
GLW_FILL_GRADIENT_COLOR_1_H, GLW_FILL_GRADIENT_COLOR_2_H);
|
||||||
|
} else {
|
||||||
|
if (0 == i) {
|
||||||
|
glwDrawLeftRoundedRectGradientFill(offset, y,
|
||||||
|
maxItemWidth, height,
|
||||||
|
GLW_BUTTON_CORNER_RADIUS,
|
||||||
|
GLW_FILL_GRADIENT_COLOR_1_H, GLW_FILL_GRADIENT_COLOR_2_H);
|
||||||
|
} else if (listLen - 1 == i) {
|
||||||
|
glwDrawRightRoundedRectGradientFill(offset, y,
|
||||||
|
maxItemWidth, height,
|
||||||
|
GLW_BUTTON_CORNER_RADIUS,
|
||||||
|
GLW_FILL_GRADIENT_COLOR_1_H, GLW_FILL_GRADIENT_COLOR_2_H);
|
||||||
|
} else {
|
||||||
|
glwDrawRectGradientFill(offset, y,
|
||||||
|
maxItemWidth, height,
|
||||||
|
GLW_FILL_GRADIENT_COLOR_1_H, GLW_FILL_GRADIENT_COLOR_2_H);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (0 != i) {
|
||||||
|
glwDrawVLine(offset, y, 1, height, GLW_BORDER_COLOR_2);
|
||||||
|
}
|
||||||
|
glwDrawSystemText(win, offset + (maxItemWidth - textSize.width) / 2,
|
||||||
|
y + height * 0.1, list[i]);
|
||||||
|
offset += maxItemWidth;
|
||||||
|
}
|
||||||
|
imGUI->nextX = offset;
|
||||||
|
imGUI->nextY = y;
|
||||||
|
glwDrawRoundedRectBorder(left, y, width, height,
|
||||||
|
GLW_BUTTON_CORNER_RADIUS, GLW_BORDER_COLOR_2);
|
||||||
|
return sel;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwImTabBox(glwWin *win, int id, int x, int y, int width, int height,
|
||||||
|
char **list, int sel) {
|
||||||
|
glwImGui *imGUI = glwGetImGUI(win);
|
||||||
|
int tabWidth = 0;
|
||||||
|
int tabHeight = 0;
|
||||||
|
int left = 0;
|
||||||
|
int i;
|
||||||
|
int listLen = 0;
|
||||||
|
int offset;
|
||||||
|
int maxItemWidth = 0;
|
||||||
|
maxItemWidth = glwCalcListMaxWidth(win, list, &tabHeight, &listLen);
|
||||||
|
tabWidth = maxItemWidth * listLen;
|
||||||
|
left = x + maxItemWidth * GLW_HOR_AUTO_MARGIN / 2;
|
||||||
|
imGUI->nextX = x;
|
||||||
|
imGUI->nextY = y + tabHeight;
|
||||||
|
glwImGUIActiveIdCheck(imGUI, id, left, y, tabWidth, tabHeight);
|
||||||
|
for (i = 0, offset = left; list[i]; ++i) {
|
||||||
|
glwSize textSize = glwMeasureSystemText(win, list[i]);
|
||||||
|
if (imGUI->activeId == id) {
|
||||||
|
int hit = glwPointTest(imGUI->mouseX, imGUI->mouseY, offset, y,
|
||||||
|
maxItemWidth, tabHeight, 0);
|
||||||
|
if (hit) {
|
||||||
|
sel = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sel == i) {
|
||||||
|
glwDrawTopRoundedRectGradientFill(offset, y,
|
||||||
|
maxItemWidth, tabHeight,
|
||||||
|
GLW_BUTTON_CORNER_RADIUS,
|
||||||
|
GLW_TAB_FILL_GRADIENT_COLOR_1, GLW_TAB_FILL_GRADIENT_COLOR_2);
|
||||||
|
glwDrawTopRoundedRectBorder(offset, y,
|
||||||
|
maxItemWidth, tabHeight,
|
||||||
|
GLW_BUTTON_CORNER_RADIUS, GLW_BORDER_COLOR_1);
|
||||||
|
}
|
||||||
|
glwDrawSystemText(win, offset + (maxItemWidth - textSize.width) / 2,
|
||||||
|
y + tabHeight * GLW_VER_AUTO_MARGIN, list[i]);
|
||||||
|
offset += maxItemWidth;
|
||||||
|
}
|
||||||
|
glwDrawRectGradientFill(x + 1, y + tabHeight,
|
||||||
|
width - 2, height - tabHeight - 2,
|
||||||
|
GLW_BACKGROUND_COLOR, GLW_BACKGROUND_COLOR);
|
||||||
|
glwDrawHLine(x, y + tabHeight - 1, width, 1, GLW_BORDER_COLOR_1);
|
||||||
|
glwDrawHLine(x, y + height - 1, width, 1, GLW_BORDER_COLOR_1);
|
||||||
|
glwDrawVLine(x, y + tabHeight, 1, height - tabHeight,
|
||||||
|
GLW_BORDER_COLOR_1);
|
||||||
|
glwDrawVLine(x + width - 1, y + tabHeight, 1, height - tabHeight,
|
||||||
|
GLW_BORDER_COLOR_1);
|
||||||
|
return sel;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwImPanel(glwWin *win, int id, int x, int y, int width, int height) {
|
||||||
|
glwDrawRectGradientFill(x, y, width, height,
|
||||||
|
GLW_PANEL_FILL_COLOR, GLW_PANEL_FILL_COLOR);
|
||||||
|
glwDrawRoundedRectBorder(x, y, width, height,
|
||||||
|
GLW_BUTTON_CORNER_RADIUS, GLW_BORDER_COLOR_1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwImToolBar(glwWin *win, int id, int x, int y, int width, int height) {
|
||||||
|
glwImGui *imGUI = glwGetImGUI(win);
|
||||||
|
glwDrawRectGradientFill(x + 1, y + 1, width - 2, height - 2,
|
||||||
|
GLW_TOOLBAR_BACKGROUND_COLOR, GLW_TOOLBAR_BACKGROUND_COLOR);
|
||||||
|
glwDrawHLine(x, y + height - 1, width, 1, GLW_BORDER_COLOR_1);
|
||||||
|
imGUI->nextX = x;
|
||||||
|
imGUI->nextY = y + height;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwImBottomBar(glwWin *win, int id, int x, int y, int width, int height) {
|
||||||
|
glwImGui *imGUI = glwGetImGUI(win);
|
||||||
|
glwDrawRectGradientFill(x + 1, y + 1, width - 2, height - 2,
|
||||||
|
GLW_TOOLBAR_BACKGROUND_COLOR, GLW_TOOLBAR_BACKGROUND_COLOR);
|
||||||
|
glwDrawHLine(x, y, width, 1, GLW_BORDER_COLOR_1);
|
||||||
|
imGUI->nextX = x;
|
||||||
|
imGUI->nextY = y - height;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwImNextX(glwWin *win) {
|
||||||
|
glwImGui *imGUI = glwGetImGUI(win);
|
||||||
|
return imGUI->nextX;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwImNextY(glwWin *win) {
|
||||||
|
glwImGui *imGUI = glwGetImGUI(win);
|
||||||
|
return imGUI->nextY;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glwImLineHeight(glwWin *win) {
|
||||||
|
glwSystemFontTexture *systemFontTexture = glwGetSystemFontTexture(win);
|
||||||
|
return systemFontTexture->originSize.height * (1 + GLW_VER_AUTO_MARGIN * 2);
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
#ifndef GLW_H
|
||||||
|
#define GLW_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct glwSize {
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
} glwSize;
|
||||||
|
|
||||||
|
typedef struct glwVec2 {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
} glwVec2;
|
||||||
|
|
||||||
|
typedef struct glwWin glwWin;
|
||||||
|
typedef struct glwFont glwFont;
|
||||||
|
|
||||||
|
#define GLW_LEFT_BUTTON 1
|
||||||
|
#define GLW_MIDDLE_BUTTON 2
|
||||||
|
#define GLW_RIGHT_BUTTON 3
|
||||||
|
|
||||||
|
#define GLW_DOWN 1
|
||||||
|
#define GLW_UP 2
|
||||||
|
|
||||||
|
void glwInit(void);
|
||||||
|
void glwMainLoop(void);
|
||||||
|
glwWin *glwCreateWindow(int x, int y, int width, int height);
|
||||||
|
glwWin *glwCreateSubWindow(glwWin *parent, int x, int y, int width, int height);
|
||||||
|
void glwSetUserData(glwWin *win, void *userData);
|
||||||
|
void *glwGetUserData(glwWin *win);
|
||||||
|
void glwDestroyWindow(glwWin *win);
|
||||||
|
void glwSetWindowTitle(glwWin *win, char *name);
|
||||||
|
void glwPositionWindow(glwWin *win, int x, int y);
|
||||||
|
void glwReshapeWindow(glwWin *win, int width, int height);
|
||||||
|
void glwDisplayFunc(glwWin *win, void (*func)(glwWin *win));
|
||||||
|
void glwReshapeFunc(glwWin *win, void (*func)(glwWin *win, int width,
|
||||||
|
int height));
|
||||||
|
void glwKeyboardFunc(glwWin *win, void (*func)(glwWin *win, unsigned char key,
|
||||||
|
int x, int y));
|
||||||
|
void glwMouseFunc(glwWin *win, void (*func)(glwWin *win, int button, int state,
|
||||||
|
int x, int y));
|
||||||
|
void glwMotionFunc(glwWin *win, void (*func)(glwWin *win, int x, int y));
|
||||||
|
void glwPassiveMotionFunc(glwWin *win, void (*func)(glwWin *win, int x, int y));
|
||||||
|
#define glwR(rgb) ((float)(((rgb) >> 16) & 0xff) / 255)
|
||||||
|
#define glwG(rgb) ((float)(((rgb) >> 8) & 0xff) / 255)
|
||||||
|
#define glwB(rgb) ((float)(((rgb)) & 0xff) / 255)
|
||||||
|
int glwImButton(glwWin *win, int id, int x, int y, char *text);
|
||||||
|
int glwImCheck(glwWin *win, int id, int x, int y, char *text, int checked);
|
||||||
|
int glwImDropdownBox(glwWin *win, int id, int x, int y, char *text);
|
||||||
|
int glwImButtonGroup(glwWin *win, int id, int x, int y, int parentWidth,
|
||||||
|
char **list, int sel);
|
||||||
|
int glwImPanel(glwWin *win, int id, int x, int y, int width, int height);
|
||||||
|
int glwImTabBox(glwWin *win, int id, int x, int y, int width, int height,
|
||||||
|
char **list, int sel);
|
||||||
|
int glwImToolBar(glwWin *win, int id, int x, int y, int width, int height);
|
||||||
|
int glwImBottomBar(glwWin *win, int id, int x, int y, int width, int height);
|
||||||
|
int glwImNextX(glwWin *win);
|
||||||
|
int glwImNextY(glwWin *win);
|
||||||
|
int glwImLineHeight(glwWin *win);
|
||||||
|
int glwPointTest(int x, int y, int left, int top, int width, int height,
|
||||||
|
int allowOffset);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef GLW_INTERNAL_H
|
||||||
|
#define GLW_INTERNAL_H
|
||||||
|
#include "glw.h"
|
||||||
|
#include "glw_style.h"
|
||||||
|
|
||||||
|
#define GLW_SYSTEM_FONT_BEGIN_CHAR ' '
|
||||||
|
#define GLW_SYSTEM_FONT_END_CHAR '~'
|
||||||
|
#define GLW_SYSTEM_FONT_CHAR_NUM (GLW_SYSTEM_FONT_END_CHAR - GLW_SYSTEM_FONT_BEGIN_CHAR + 1)
|
||||||
|
|
||||||
|
#define GLW_TEXT_ALIGN_LEFT 0
|
||||||
|
#define GLW_TEXT_ALIGN_CENTER 1
|
||||||
|
#define GLW_TEXT_ALIGN_RIGHT 2
|
||||||
|
|
||||||
|
typedef enum glwCtrlState {
|
||||||
|
GLW_CTRL_STATE_NORMAL,
|
||||||
|
GLW_CTRL_STATE_PRESS,
|
||||||
|
} glwCtrlState;
|
||||||
|
|
||||||
|
typedef struct glwSystemFontTexture {
|
||||||
|
int texId;
|
||||||
|
glwSize size;
|
||||||
|
glwSize originSize;
|
||||||
|
float lefts[GLW_SYSTEM_FONT_CHAR_NUM];
|
||||||
|
int widths[GLW_SYSTEM_FONT_CHAR_NUM];
|
||||||
|
} glwSystemFontTexture;
|
||||||
|
|
||||||
|
typedef struct glwImGui {
|
||||||
|
int mouseButton;
|
||||||
|
int mouseState;
|
||||||
|
int mouseX;
|
||||||
|
int mouseY;
|
||||||
|
int activeId;
|
||||||
|
int nextX;
|
||||||
|
int nextY;
|
||||||
|
} glwImGui;
|
||||||
|
|
||||||
|
glwSize glwMeasureText(char *text, glwFont *font);
|
||||||
|
unsigned char *glwRenderTextToRGBA(char *text, glwFont *font, glwSize size,
|
||||||
|
int *pixelsWide, int *pixelsHigh);
|
||||||
|
void glwDrawText(int x, int y, char *text, glwFont *font);
|
||||||
|
void glwDrawSystemText(glwWin *win, int x, int y, char *text);
|
||||||
|
glwSize glwMeasureSystemText(glwWin *win, char *text);
|
||||||
|
void glwInitSystemFontTexture(glwWin *win);
|
||||||
|
void glwInitPrimitives(void);
|
||||||
|
glwSystemFontTexture *glwGetSystemFontTexture(glwWin *win);
|
||||||
|
void glwDestroyFont(glwFont *font);
|
||||||
|
glwFont *glwCreateFont(char *name, int weight, int size, int bold);
|
||||||
|
void glwDestroyFont(glwFont *font);
|
||||||
|
void glwDrawButtonBackground(float x, float y, float width, float height,
|
||||||
|
glwCtrlState state);
|
||||||
|
void glwMouseEvent(glwWin *win, int button, int state, int x, int y);
|
||||||
|
glwImGui *glwGetImGUI(glwWin *win);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,345 @@
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <QuartzCore/QuartzCore.h>
|
||||||
|
#import <OpenGL/gl.h>
|
||||||
|
#include "glw_internal.h"
|
||||||
|
|
||||||
|
@interface GLView : NSOpenGLView <NSWindowDelegate> {
|
||||||
|
CVDisplayLinkRef displayLink;
|
||||||
|
@public
|
||||||
|
void (*onReshape)(glwWin *win, int width, int height);
|
||||||
|
void (*onDisplay)(glwWin *win);
|
||||||
|
void (*onMouse)(glwWin *win, int button, int state, int x, int y);
|
||||||
|
void (*onMotion)(glwWin *win, int x, int y);
|
||||||
|
void (*onPassiveMotion)(glwWin *win, int x, int y);
|
||||||
|
void *userData;
|
||||||
|
int pendingReshape;
|
||||||
|
int viewWidth;
|
||||||
|
int viewHeight;
|
||||||
|
float scaleX;
|
||||||
|
float scaleY;
|
||||||
|
glwSystemFontTexture systemFontTexture;
|
||||||
|
glwImGui imGUI;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CVReturn)getFrameForTime:(const CVTimeStamp *)outputTime;
|
||||||
|
- (void)drawFrame;
|
||||||
|
@end
|
||||||
|
|
||||||
|
static CVReturn onDisplayLinkCallback(CVDisplayLinkRef displayLink,
|
||||||
|
const CVTimeStamp *now, const CVTimeStamp *outputTime,
|
||||||
|
CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext)
|
||||||
|
{
|
||||||
|
CVReturn result = [(GLView *)displayLinkContext getFrameForTime:outputTime];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
glwSystemFontTexture *glwGetSystemFontTexture(glwWin *win) {
|
||||||
|
GLView *view = ((NSWindow *)win).contentView;
|
||||||
|
return &view->systemFontTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
@implementation GLView
|
||||||
|
- (id)initWithFrame:(NSRect)frameRect {
|
||||||
|
NSOpenGLPixelFormatAttribute attribs[] = {NSOpenGLPFAMultisample,
|
||||||
|
NSOpenGLPFASampleBuffers, 1,
|
||||||
|
NSOpenGLPFASamples, 0,
|
||||||
|
NSOpenGLPFAAccelerated,
|
||||||
|
NSOpenGLPFADoubleBuffer,
|
||||||
|
NSOpenGLPFAColorSize, 32,
|
||||||
|
NSOpenGLPFADepthSize, 24,
|
||||||
|
NSOpenGLPFAAlphaSize, 8,
|
||||||
|
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy,
|
||||||
|
0};
|
||||||
|
NSOpenGLPixelFormat *windowedPixelFormat = [[NSOpenGLPixelFormat alloc]
|
||||||
|
initWithAttributes:attribs];
|
||||||
|
self = [super initWithFrame:frameRect pixelFormat:windowedPixelFormat];
|
||||||
|
[windowedPixelFormat release];
|
||||||
|
|
||||||
|
[self setWantsBestResolutionOpenGLSurface:YES];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) prepareOpenGL {
|
||||||
|
[super prepareOpenGL];
|
||||||
|
|
||||||
|
GLint vblSynch = 1;
|
||||||
|
[[self openGLContext] setValues:&vblSynch
|
||||||
|
forParameter:NSOpenGLCPSwapInterval];
|
||||||
|
|
||||||
|
CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
|
||||||
|
CVDisplayLinkSetOutputCallback(displayLink, onDisplayLinkCallback, self);
|
||||||
|
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink,
|
||||||
|
[[self openGLContext] CGLContextObj],
|
||||||
|
[[self pixelFormat] CGLPixelFormatObj]);
|
||||||
|
|
||||||
|
CVDisplayLinkStart(displayLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)drawFrame {
|
||||||
|
@autoreleasepool {
|
||||||
|
NSOpenGLContext *currentContext = [self openGLContext];
|
||||||
|
[currentContext makeCurrentContext];
|
||||||
|
CGLLockContext([currentContext CGLContextObj]);
|
||||||
|
if (self->pendingReshape) {
|
||||||
|
if (self->onReshape) {
|
||||||
|
self->pendingReshape = 0;
|
||||||
|
if (!self->systemFontTexture.texId) {
|
||||||
|
glwInitSystemFontTexture((glwWin *)self.window);
|
||||||
|
}
|
||||||
|
self->onReshape((glwWin *)self.window, self->viewWidth,
|
||||||
|
self->viewHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self->onDisplay) {
|
||||||
|
self->onDisplay((glwWin *)self.window);
|
||||||
|
}
|
||||||
|
CGLFlushDrawable([[self openGLContext] CGLContextObj]);
|
||||||
|
CGLUnlockContext([currentContext CGLContextObj]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CVReturn)getFrameForTime:(const CVTimeStamp *)outputTime {
|
||||||
|
[self drawFrame];
|
||||||
|
return kCVReturnSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
CVDisplayLinkRelease(displayLink);
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)acceptsFirstResponder {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)reshape {
|
||||||
|
NSRect bounds = [self bounds];
|
||||||
|
NSRect backingBounds = [self convertRectToBacking:[self bounds]];
|
||||||
|
viewWidth = (int)backingBounds.size.width;
|
||||||
|
viewHeight = (int)backingBounds.size.height;
|
||||||
|
self->scaleX = (float)viewWidth / bounds.size.width;
|
||||||
|
self->scaleY = (float)viewHeight / bounds.size.height;
|
||||||
|
self->pendingReshape = 1;
|
||||||
|
[self drawFrame];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)resumeDisplayRenderer {
|
||||||
|
NSOpenGLContext *currentContext = [self openGLContext];
|
||||||
|
[currentContext makeCurrentContext];
|
||||||
|
CGLLockContext([currentContext CGLContextObj]);
|
||||||
|
CVDisplayLinkStart(displayLink);
|
||||||
|
CGLUnlockContext([currentContext CGLContextObj]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)haltDisplayRenderer {
|
||||||
|
NSOpenGLContext *currentContext = [self openGLContext];
|
||||||
|
[currentContext makeCurrentContext];
|
||||||
|
CGLLockContext([currentContext CGLContextObj]);
|
||||||
|
CVDisplayLinkStop(displayLink);
|
||||||
|
CGLUnlockContext([currentContext CGLContextObj]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseMoved:(NSEvent*)event {
|
||||||
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
|
||||||
|
int x = loc.x * self->scaleX;
|
||||||
|
int y = loc.y * self->scaleY;
|
||||||
|
if (GLW_DOWN == self->imGUI.mouseState) {
|
||||||
|
if (self->onMotion) {
|
||||||
|
self->onMotion((glwWin *)self.window, x, y);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (self->onPassiveMotion) {
|
||||||
|
self->onPassiveMotion((glwWin *)self.window, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseDown:(NSEvent*)event {
|
||||||
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
|
||||||
|
int x = loc.x * self->scaleX;
|
||||||
|
int y = loc.y * self->scaleY;
|
||||||
|
glwMouseEvent((glwWin *)self.window, GLW_LEFT_BUTTON, GLW_DOWN, x, y);
|
||||||
|
if (self->onMouse) {
|
||||||
|
self->onMouse((glwWin *)self.window, GLW_LEFT_BUTTON, GLW_DOWN, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseDragged:(NSEvent *)event {
|
||||||
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
|
||||||
|
int x = loc.x * self->scaleX;
|
||||||
|
int y = loc.y * self->scaleY;
|
||||||
|
if (GLW_DOWN == self->imGUI.mouseState) {
|
||||||
|
if (GLW_DOWN == self->imGUI.mouseState) {
|
||||||
|
if (self->onMotion) {
|
||||||
|
self->onMotion((glwWin *)self.window, x, y);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (self->onPassiveMotion) {
|
||||||
|
self->onPassiveMotion((glwWin *)self.window, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
glwMouseEvent((glwWin *)self.window, GLW_LEFT_BUTTON, GLW_DOWN, x, y);
|
||||||
|
if (self->onMouse) {
|
||||||
|
self->onMouse((glwWin *)self.window, GLW_LEFT_BUTTON, GLW_DOWN, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isFlipped {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseUp:(NSEvent*)event {
|
||||||
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
|
||||||
|
int x = loc.x * self->scaleX;
|
||||||
|
int y = loc.y * self->scaleY;
|
||||||
|
glwMouseEvent((glwWin *)self.window, GLW_LEFT_BUTTON, GLW_UP, x, y);
|
||||||
|
if (self->onMouse) {
|
||||||
|
self->onMouse((glwWin *)self.window, GLW_LEFT_BUTTON, GLW_UP, x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
glwImGui *glwGetImGUI(glwWin *win) {
|
||||||
|
GLView *view = ((NSWindow *)win).contentView;
|
||||||
|
return &view->imGUI;
|
||||||
|
}
|
||||||
|
|
||||||
|
glwFont *glwCreateFont(char *name, int weight, int size, int bold) {
|
||||||
|
NSString *fontFamily = [NSString stringWithCString:name
|
||||||
|
encoding:NSMacOSRomanStringEncoding];
|
||||||
|
NSFont *font = [[[NSFontManager sharedFontManager] fontWithFamily:fontFamily
|
||||||
|
traits:(bold ? NSBoldFontMask : NSUnboldFontMask) weight:weight size:size] retain];
|
||||||
|
return (glwFont *)font;
|
||||||
|
}
|
||||||
|
|
||||||
|
glwSize glwMeasureText(char *text, glwFont *font) {
|
||||||
|
NSString *aString = [NSString stringWithCString:text
|
||||||
|
encoding:NSMacOSRomanStringEncoding];
|
||||||
|
NSSize frameSize = [aString sizeWithAttributes:
|
||||||
|
[NSDictionary dictionaryWithObject:(NSFont *)font forKey:NSFontAttributeName]];
|
||||||
|
glwSize size = {frameSize.width, frameSize.height};
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwInit(void) {
|
||||||
|
[NSApplication sharedApplication];
|
||||||
|
glwInitPrimitives();
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwMainLoop(void) {
|
||||||
|
@autoreleasepool {
|
||||||
|
[NSApp run];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwSetUserData(glwWin *win, void *userData) {
|
||||||
|
GLView *view = ((NSWindow *)win).contentView;
|
||||||
|
view->userData = userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *glwGetUserData(glwWin *win) {
|
||||||
|
GLView *view = ((NSWindow *)win).contentView;
|
||||||
|
return view->userData;
|
||||||
|
}
|
||||||
|
|
||||||
|
glwWin *glwCreateWindow(int x, int y, int width, int height) {
|
||||||
|
NSUInteger windowStyle = NSTitledWindowMask | NSClosableWindowMask |
|
||||||
|
NSResizableWindowMask | NSMiniaturizableWindowMask;
|
||||||
|
NSRect fullRect = [[NSScreen mainScreen] visibleFrame];
|
||||||
|
|
||||||
|
if (0 == width || 0 == height) {
|
||||||
|
width = fullRect.size.width;
|
||||||
|
height = fullRect.size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSRect viewRect = NSMakeRect(0, 0, width, height);
|
||||||
|
NSRect windowRect = NSMakeRect(x, y, width, height);
|
||||||
|
|
||||||
|
NSWindow *window = [[NSWindow alloc] initWithContentRect:windowRect
|
||||||
|
styleMask:windowStyle
|
||||||
|
backing:NSBackingStoreBuffered
|
||||||
|
defer:NO];
|
||||||
|
|
||||||
|
GLView *view = [[GLView alloc] initWithFrame:viewRect];
|
||||||
|
view->onReshape = 0;
|
||||||
|
view->onDisplay = 0;
|
||||||
|
view->onMouse = 0;
|
||||||
|
view->userData = 0;
|
||||||
|
view->pendingReshape = 0;
|
||||||
|
view->viewWidth = width;
|
||||||
|
view->viewHeight = height;
|
||||||
|
view->systemFontTexture.texId = 0;
|
||||||
|
memset(&view->imGUI, 0, sizeof(view->imGUI));
|
||||||
|
view->scaleX = 1;
|
||||||
|
view->scaleY = 1;
|
||||||
|
view->onPassiveMotion = 0;
|
||||||
|
view->onMotion = 0;
|
||||||
|
|
||||||
|
[window setAcceptsMouseMovedEvents:YES];
|
||||||
|
[window setContentView:view];
|
||||||
|
[window setDelegate:view];
|
||||||
|
|
||||||
|
[window orderFrontRegardless];
|
||||||
|
|
||||||
|
return (glwWin *)window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDisplayFunc(glwWin *win, void (*func)(glwWin *win)) {
|
||||||
|
GLView *view = ((NSWindow *)win).contentView;
|
||||||
|
view->onDisplay = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwReshapeFunc(glwWin *win, void (*func)(glwWin *win, int width,
|
||||||
|
int height)) {
|
||||||
|
GLView *view = ((NSWindow *)win).contentView;
|
||||||
|
view->onReshape = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwMouseFunc(glwWin *win, void (*func)(glwWin *win, int button, int state,
|
||||||
|
int x, int y)) {
|
||||||
|
GLView *view = ((NSWindow *)win).contentView;
|
||||||
|
view->onMouse = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwMotionFunc(glwWin *win,
|
||||||
|
void (*func)(glwWin *win, int x, int y)) {
|
||||||
|
GLView *view = ((NSWindow *)win).contentView;
|
||||||
|
view->onMotion = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwPassiveMotionFunc(glwWin *win,
|
||||||
|
void (*func)(glwWin *win, int x, int y)) {
|
||||||
|
GLView *view = ((NSWindow *)win).contentView;
|
||||||
|
view->onPassiveMotion = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *glwRenderTextToRGBA(char *text, glwFont *font, glwSize size,
|
||||||
|
int *pixelsWide, int *pixelsHigh) {
|
||||||
|
NSString *aString = [NSString stringWithCString:text encoding:NSMacOSRomanStringEncoding];
|
||||||
|
NSSize frameSize = NSMakeSize(size.width, size.height);
|
||||||
|
NSImage *image = [[NSImage alloc] initWithSize:frameSize];
|
||||||
|
unsigned char *rgba = 0;
|
||||||
|
int rgbaBytes = 0;
|
||||||
|
[image lockFocus];
|
||||||
|
[aString drawAtPoint:NSMakePoint(0, 0) withAttributes:
|
||||||
|
[NSDictionary dictionaryWithObject:(NSFont *)font forKey:NSFontAttributeName]];
|
||||||
|
[image unlockFocus];
|
||||||
|
NSBitmapImageRep *bitmap = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
|
||||||
|
*pixelsWide = [bitmap pixelsWide];
|
||||||
|
*pixelsHigh = [bitmap pixelsHigh];
|
||||||
|
rgbaBytes = 4 * (*pixelsWide) * (*pixelsHigh);
|
||||||
|
rgba = malloc(rgbaBytes);
|
||||||
|
memcpy(rgba, [bitmap bitmapData], rgbaBytes);
|
||||||
|
[image release];
|
||||||
|
return rgba;
|
||||||
|
}
|
||||||
|
|
||||||
|
void glwDestroyFont(glwFont *font) {
|
||||||
|
NSFont *nsFont = (NSFont *)font;
|
||||||
|
[nsFont release];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef GLW_STYLE_H
|
||||||
|
#define GLW_STYLE_H
|
||||||
|
|
||||||
|
#define GLW_SYSTEM_FONT_NAME "Helvetica"
|
||||||
|
#define GLW_SYSTEM_FONT_WEIGHT 5
|
||||||
|
#define GLW_SYSTEM_FONT_SIZE 20
|
||||||
|
|
||||||
|
#define GLW_SMALL_ROUNDED_CORNER_SLICES 5
|
||||||
|
|
||||||
|
#define GLW_BORDER_COLOR_1 0xa2a2a2
|
||||||
|
#define GLW_BORDER_COLOR_2 0x616161
|
||||||
|
|
||||||
|
#define GLW_FILL_GRADIENT_COLOR_1 0xffffff
|
||||||
|
#define GLW_FILL_GRADIENT_COLOR_2 0xc6c4c5
|
||||||
|
|
||||||
|
#define GLW_FILL_GRADIENT_COLOR_1_H 0x3795fa
|
||||||
|
#define GLW_FILL_GRADIENT_COLOR_2_H 0x333333
|
||||||
|
|
||||||
|
#define GLW_BUTTON_CORNER_RADIUS 5
|
||||||
|
|
||||||
|
#define GLW_CHECK_COLOR 0x000000
|
||||||
|
|
||||||
|
#define GLW_TAB_FILL_GRADIENT_COLOR_1 0xffffff
|
||||||
|
#define GLW_TAB_FILL_GRADIENT_COLOR_2 0xc6c4c5
|
||||||
|
|
||||||
|
#define GLW_TAB_FILL_GRADIENT_COLOR_1_H 0x3795fa
|
||||||
|
#define GLW_TAB_FILL_GRADIENT_COLOR_2_H 0x333333
|
||||||
|
|
||||||
|
#define GLW_PANEL_FILL_COLOR 0xe2e2e2
|
||||||
|
|
||||||
|
#define GLW_HOR_AUTO_MARGIN 0.4
|
||||||
|
#define GLW_VER_AUTO_MARGIN 0.15
|
||||||
|
|
||||||
|
#define GLW_BACKGROUND_COLOR 0xfcfcfc
|
||||||
|
#define GLW_TOOLBAR_BACKGROUND_COLOR 0xf5f5f5
|
||||||
|
|
||||||
|
#endif
|
|
@ -13,9 +13,14 @@ typedef struct skinnedMeshVertex {
|
||||||
} skinnedMeshVertex;
|
} skinnedMeshVertex;
|
||||||
|
|
||||||
typedef struct skinnedMeshBone {
|
typedef struct skinnedMeshBone {
|
||||||
vec3 translation;
|
vec3 position;
|
||||||
vec3 rotation;
|
vec3 rotation;
|
||||||
matrix toRoot;
|
matrix toRoot;
|
||||||
} skinnedMeshBone;
|
} skinnedMeshBone;
|
||||||
|
|
||||||
|
typedef struct skinnedMesh skinnedMesh;
|
||||||
|
|
||||||
|
skinnedMesh *skinnedMeshCreate(void);
|
||||||
|
void skinnedMeshAddBone();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "osutil.h"
|
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
#include <QGLWidget>
|
||||||
|
#include "osutil.h"
|
||||||
|
|
||||||
long long osGetMilliseconds(void) {
|
long long osGetMilliseconds(void) {
|
||||||
return (long long)QDateTime::currentMSecsSinceEpoch();
|
return (long long)QDateTime::currentMSecsSinceEpoch();
|
|
@ -5,8 +5,16 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
long long osGetMilliseconds(void);
|
long long osGetMilliseconds(void);
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265358979323846
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define unsued(param) (void)param
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue