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)
|
24
README.md
24
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.
|
||||
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
|
||||
==============
|
||||
- [x] Drawing Primitives (Dec 15, 2016 ~ Dec 17, 2016)
|
||||
|
@ -83,7 +64,10 @@ This todo already done in the B-Mesh algorithm implementation.
|
|||
**Feb 8, 2017:**
|
||||
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!
|
||||
<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
|
||||
- [ ] 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 "convexhull.h"
|
||||
#include "subdivide.h"
|
||||
#include "draw.h"
|
||||
|
||||
#define BMESH_MAX_PARENT_BALL_DEPTH 1000
|
||||
#define BMESH_INTVAL_DIST_DIV 10
|
||||
|
@ -547,10 +546,6 @@ static convexHull *createConvexHullForBall(bmesh *bm, int depth,
|
|||
for (i = 0; i < arrayGetLength(ballPtrArray); ++i) {
|
||||
bmeshBall *ballItem = *((bmeshBall **)arrayGetItem(ballPtrArray, i));
|
||||
ballItem->convexHullCount++;
|
||||
drawDebugPrintf("convexHullCount:%d", ballItem->convexHullCount);
|
||||
if (ballItem->convexHullCount == 1) {
|
||||
drawDebugPoint(&ballItem->position, ballItem->index);
|
||||
}
|
||||
}
|
||||
|
||||
arrayDestroy(ballPtrArray);
|
||||
|
@ -727,7 +722,7 @@ static void bmeshGenerateInbetweenMeshFrom(bmesh *bm, int depth,
|
|||
bmeshAddWallsBetweenQuadsToModel(bm, &ball->position, ¤tFace,
|
||||
&childFace);
|
||||
bmeshAddQuadToModel(bm, &childFace);
|
||||
drawQuad(&childFace);
|
||||
//drawQuad(&childFace);
|
||||
}
|
||||
}
|
||||
else if (1 == ball->convexHullCount && !ball->meshGenerated) {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "convexhull.h"
|
||||
#include "array.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
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#include <QtGui>
|
||||
#include <QtOpenGL>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <math.h>
|
||||
#include "draw.h"
|
||||
|
||||
static GLUquadricObj *quadricId = 0;
|
||||
|
@ -88,8 +87,6 @@ int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices,
|
|||
}
|
||||
|
||||
int drawGrid(float size, float step) {
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
// x z plane
|
||||
glBegin(GL_LINES);
|
||||
for (GLfloat i = -size; i <= size; i += step) {
|
||||
|
@ -105,8 +102,6 @@ int drawGrid(float size, float step) {
|
|||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -115,7 +110,8 @@ int drawPrintf(int x, int y, const char *fmt, ...) {
|
|||
char text[1024];
|
||||
va_start(args, fmt);
|
||||
vsnprintf(text, sizeof(text), fmt, args);
|
||||
return drawText(x, y, text);
|
||||
//return drawText(x, y, text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const float drawDebugColors[][4] = {
|
|
@ -12,6 +12,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265
|
||||
#endif
|
||||
|
||||
int drawInit(void);
|
||||
int drawSphere(vec3 *origin, float radius, int slices, int stacks);
|
||||
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;
|
||||
|
||||
typedef struct skinnedMeshBone {
|
||||
vec3 translation;
|
||||
vec3 position;
|
||||
vec3 rotation;
|
||||
matrix toRoot;
|
||||
} skinnedMeshBone;
|
||||
|
||||
typedef struct skinnedMesh skinnedMesh;
|
||||
|
||||
skinnedMesh *skinnedMeshCreate(void);
|
||||
void skinnedMeshAddBone();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "osutil.h"
|
||||
#include <QDateTime>
|
||||
#include <QGLWidget>
|
||||
#include "osutil.h"
|
||||
|
||||
long long osGetMilliseconds(void) {
|
||||
return (long long)QDateTime::currentMSecsSinceEpoch();
|
|
@ -5,8 +5,16 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
long long osGetMilliseconds(void);
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define unsued(param) (void)param
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue