Replaced view cube with a sphere.

This commit is contained in:
Leonardo Zide 2018-10-28 17:59:01 -07:00
parent 58c63982d2
commit b77b9aac5c
17 changed files with 564 additions and 475 deletions

View file

@ -25,8 +25,8 @@ void lcPreferences::LoadDefaults()
mDrawGridLines = lcGetProfileInt(LC_PROFILE_GRID_LINES);
mGridLineSpacing = lcGetProfileInt(LC_PROFILE_GRID_LINE_SPACING);
mGridLineColor = lcGetProfileInt(LC_PROFILE_GRID_LINE_COLOR);
mViewCubeLocation = (lcViewCubeLocation)lcGetProfileInt(LC_PROFILE_VIEW_CUBE_LOCATION);
mViewCubeSize = lcGetProfileInt(LC_PROFILE_VIEW_CUBE_SIZE);
mViewSphereLocation = (lcViewSphereLocation)lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_LOCATION);
mViewSphereSize = lcGetProfileInt(LC_PROFILE_VIEW_SPHERE_SIZE);
}
void lcPreferences::SaveDefaults()
@ -42,8 +42,8 @@ void lcPreferences::SaveDefaults()
lcSetProfileInt(LC_PROFILE_GRID_LINES, mDrawGridLines);
lcSetProfileInt(LC_PROFILE_GRID_LINE_SPACING, mGridLineSpacing);
lcSetProfileInt(LC_PROFILE_GRID_LINE_COLOR, mGridLineColor);
lcSetProfileInt(LC_PROFILE_VIEW_CUBE_LOCATION, (int)mViewCubeLocation);
lcSetProfileInt(LC_PROFILE_VIEW_CUBE_SIZE, mViewCubeSize);
lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_LOCATION, (int)mViewSphereLocation);
lcSetProfileInt(LC_PROFILE_VIEW_SPHERE_SIZE, mViewSphereSize);
}
lcApplication::lcApplication(int& Argc, char** Argv)

View file

@ -14,7 +14,7 @@ enum lcShadingMode
LC_NUM_SHADING_MODES
};
enum class lcViewCubeLocation
enum class lcViewSphereLocation
{
DISABLED,
TOP_LEFT,
@ -40,8 +40,8 @@ public:
int mGridLineSpacing;
quint32 mGridLineColor;
bool mFixedAxes;
lcViewCubeLocation mViewCubeLocation;
int mViewCubeSize;
lcViewSphereLocation mViewSphereLocation;
int mViewSphereSize;
};
class lcApplication : public QApplication

View file

@ -34,6 +34,7 @@ lcContext::lcContext()
mTexture2D = 0;
mTexture2DMS = 0;
mTextureCubeMap = 0;
mLineWidth = 1.0f;
#ifndef LC_OPENGLES
mMatrixMode = GL_MODELVIEW;
@ -47,11 +48,13 @@ lcContext::lcContext()
mViewMatrix = lcMatrix44Identity();
mProjectionMatrix = lcMatrix44Identity();
mViewProjectionMatrix = lcMatrix44Identity();
mHighlightColor = lcVector4(0.0f, 0.0f, 0.0f, 0.0f);
mColorDirty = false;
mWorldMatrixDirty = false;
mViewMatrixDirty = false;
mProjectionMatrixDirty = false;
mViewProjectionMatrixDirty = false;
mHighlightColorDirty = false;
mMaterialType = LC_NUM_MATERIALS;
}
@ -130,6 +133,16 @@ void lcContext::CreateShaderPrograms()
" gl_Position = WorldViewProjectionMatrix * vec4(VertexPosition, 1.0);\n"
" PixelColor = VertexColor;\n"
"}\n",
// LC_MATERIAL_UNLIT_VIEW_SPHERE
LC_SHADER_VERSION
LC_VERTEX_INPUT "vec3 VertexPosition;\n"
LC_VERTEX_OUTPUT "vec3 PixelNormal;\n"
"uniform mat4 WorldViewProjectionMatrix;\n"
"void main()\n"
"{\n"
" PixelNormal = normalize(VertexPosition);\n"
" gl_Position = WorldViewProjectionMatrix * vec4(VertexPosition, 1.0);\n"
"}\n",
// LC_MATERIAL_FAKELIT_COLOR
LC_SHADER_VERSION
LC_VERTEX_INPUT "vec3 VertexPosition;\n"
@ -181,7 +194,7 @@ void lcContext::CreateShaderPrograms()
"uniform sampler2D Texture;\n"
"void main()\n"
"{\n"
LC_SHADER_PRECISION " vec4 TexelColor = texture2D(Texture, PixelTexCoord);"
LC_SHADER_PRECISION " vec4 TexelColor = texture2D(Texture, PixelTexCoord);\n"
" gl_FragColor = vec4(MaterialColor.rgb, TexelColor.a * MaterialColor.a);\n"
"}\n",
// LC_MATERIAL_UNLIT_TEXTURE_DECAL
@ -192,7 +205,7 @@ void lcContext::CreateShaderPrograms()
"uniform sampler2D Texture;\n"
"void main()\n"
"{\n"
LC_SHADER_PRECISION " vec4 TexelColor = texture2D(Texture, PixelTexCoord);"
LC_SHADER_PRECISION " vec4 TexelColor = texture2D(Texture, PixelTexCoord);\n"
" gl_FragColor = mix(MaterialColor, TexelColor, TexelColor.a);\n"
"}\n",
// LC_MATERIAL_UNLIT_VERTEX_COLOR
@ -203,6 +216,18 @@ void lcContext::CreateShaderPrograms()
"{\n"
" gl_FragColor = PixelColor;\n"
"}\n",
// LC_MATERIAL_UNLIT_VIEW_SPHERE
LC_SHADER_VERSION
LC_PIXEL_INPUT "vec3 PixelNormal;\n"
LC_PIXEL_OUTPUT
"uniform mediump vec4 MaterialColor;\n"
"uniform mediump vec4 HighlightColor;\n"
"uniform samplerCube Texture;\n"
"void main()\n"
"{\n"
" float TexelAlpha = textureCube(Texture, PixelNormal).a;\n"
" gl_FragColor = mix(MaterialColor, HighlightColor, TexelAlpha);\n"
"}\n",
// LC_MATERIAL_FAKELIT_COLOR
LC_SHADER_VERSION
LC_PIXEL_INPUT "vec3 PixelPosition;\n"
@ -318,6 +343,7 @@ void lcContext::CreateShaderPrograms()
mPrograms[MaterialType].MaterialColorLocation = glGetUniformLocation(Program, "MaterialColor");
mPrograms[MaterialType].LightPositionLocation = glGetUniformLocation(Program, "LightPosition");
mPrograms[MaterialType].EyePositionLocation = glGetUniformLocation(Program, "EyePosition");
mPrograms[MaterialType].HighlightColorLocation = glGetUniformLocation(Program, "HighlightColor");
}
}
@ -401,6 +427,8 @@ void lcContext::SetDefaultState()
mTexture2DMS = 0;
}
#endif
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
mTextureCubeMap = 0;
glLineWidth(1.0f);
mLineWidth = 1.0f;
@ -444,6 +472,7 @@ void lcContext::SetMaterial(lcMaterialType MaterialType)
mColorDirty = true;
mWorldMatrixDirty = true; // todo: change dirty to a bitfield and set the lighting constants dirty here
mViewMatrixDirty = true;
mHighlightColorDirty = true;
}
else
{
@ -533,6 +562,15 @@ void lcContext::BindTexture2DMS(GLuint Texture)
#endif
}
void lcContext::BindTextureCubeMap(GLuint Texture)
{
if (mTextureCubeMap == Texture)
return;
glBindTexture(GL_TEXTURE_CUBE_MAP, Texture);
mTextureCubeMap = Texture;
}
void lcContext::UnbindTexture2D(GLuint Texture)
{
if (mTexture2D != Texture)
@ -542,6 +580,15 @@ void lcContext::UnbindTexture2D(GLuint Texture)
mTexture2D = 0;
}
void lcContext::UnbindTextureCubeMap(GLuint Texture)
{
if (mTextureCubeMap != Texture)
return;
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
mTextureCubeMap = 0;
}
void lcContext::SetColor(float Red, float Green, float Blue, float Alpha)
{
SetColor(lcVector4(Red, Green, Blue, Alpha));
@ -1265,6 +1312,12 @@ void lcContext::FlushState()
glUniform4fv(Program.MaterialColorLocation, 1, mColor);
mColorDirty = false;
}
if (mHighlightColorDirty && Program.HighlightColorLocation != -1)
{
glUniform4fv(Program.HighlightColorLocation, 1, mHighlightColor);
mHighlightColorDirty = false;
}
}
else
{

View file

@ -51,6 +51,7 @@ enum lcMaterialType
LC_MATERIAL_UNLIT_TEXTURE_MODULATE,
LC_MATERIAL_UNLIT_TEXTURE_DECAL,
LC_MATERIAL_UNLIT_VERTEX_COLOR,
LC_MATERIAL_UNLIT_VIEW_SPHERE,
LC_MATERIAL_FAKELIT_COLOR,
LC_MATERIAL_FAKELIT_TEXTURE_DECAL,
LC_NUM_MATERIALS
@ -72,6 +73,7 @@ struct lcProgram
GLint MaterialColorLocation;
GLint LightPositionLocation;
GLint EyePositionLocation;
GLint HighlightColorLocation;
};
class lcFramebuffer
@ -140,8 +142,10 @@ public:
void SetLineWidth(float LineWidth);
void SetSmoothShading(bool Smooth);
void BindTexture2D(GLuint Texture);
void UnbindTexture2D(GLuint Texture);
void BindTexture2DMS(GLuint Texture);
void BindTextureCubeMap(GLuint Texture);
void UnbindTexture2D(GLuint Texture);
void UnbindTextureCubeMap(GLuint Texture);
void SetColor(const lcVector4& Color)
{
@ -149,6 +153,12 @@ public:
mColorDirty = true;
}
void SetHighlightColor(const lcVector4& HighlightColor)
{
mHighlightColor = HighlightColor;
mHighlightColorDirty = true;
}
void SetColor(float Red, float Green, float Blue, float Alpha);
void SetColorIndex(int ColorIndex);
void SetColorIndexTinted(int ColorIndex, lcInterfaceColor InterfaceColor, float Weight);
@ -206,6 +216,7 @@ protected:
GLuint mTexture2D;
GLuint mTexture2DMS;
GLuint mTextureCubeMap;
float mLineWidth;
int mMatrixMode;
bool mTextureEnabled;
@ -215,11 +226,13 @@ protected:
lcMatrix44 mViewMatrix;
lcMatrix44 mProjectionMatrix;
lcMatrix44 mViewProjectionMatrix;
lcVector4 mHighlightColor;
bool mColorDirty;
bool mWorldMatrixDirty;
bool mViewMatrixDirty;
bool mProjectionMatrixDirty;
bool mViewProjectionMatrixDirty;
bool mHighlightColorDirty;
GLuint mFramebufferObject;

View file

@ -55,66 +55,66 @@ lcProfileEntry::lcProfileEntry(const char* Section, const char* Key)
lcProfileEntry gProfileEntries[LC_NUM_PROFILE_KEYS] =
{
lcProfileEntry("Settings", "FixedAxes", false), // LC_PROFILE_FIXED_AXES
lcProfileEntry("Settings", "LineWidth", 1.0f), // LC_PROFILE_LINE_WIDTH
lcProfileEntry("Settings", "ShadingMode", LC_SHADING_DEFAULT_LIGHTS), // LC_PROFILE_SHADING_MODE
lcProfileEntry("Settings", "DrawAxes", 0), // LC_PROFILE_DRAW_AXES
lcProfileEntry("Settings", "DrawEdgeLines", 1), // LC_PROFILE_DRAW_EDGE_LINES
lcProfileEntry("Settings", "GridStuds", 1), // LC_PROFILE_GRID_STUDS
lcProfileEntry("Settings", "GridStudColor", LC_RGBA(64, 64, 64, 192)), // LC_PROFILE_GRID_STUD_COLOR
lcProfileEntry("Settings", "GridLines", 1), // LC_PROFILE_GRID_LINES
lcProfileEntry("Settings", "GridLineSpacing", 5), // LC_PROFILE_GRID_LINE_SPACING
lcProfileEntry("Settings", "GridLineColor", LC_RGBA(0, 0, 0, 255)), // LC_PROFILE_GRID_LINE_COLOR
lcProfileEntry("Settings", "AASamples", 1), // LC_PROFILE_ANTIALIASING_SAMPLES
lcProfileEntry("Settings", "ViewCubeLocation", (int)lcViewCubeLocation::TOP_RIGHT), // LC_PROFILE_VIEW_CUBE_LOCATION
lcProfileEntry("Settings", "ViewCubeSize", 100), // LC_PROFILE_VIEW_CUBE_SIZE
lcProfileEntry("Settings", "FixedAxes", false), // LC_PROFILE_FIXED_AXES
lcProfileEntry("Settings", "LineWidth", 1.0f), // LC_PROFILE_LINE_WIDTH
lcProfileEntry("Settings", "ShadingMode", LC_SHADING_DEFAULT_LIGHTS), // LC_PROFILE_SHADING_MODE
lcProfileEntry("Settings", "DrawAxes", 0), // LC_PROFILE_DRAW_AXES
lcProfileEntry("Settings", "DrawEdgeLines", 1), // LC_PROFILE_DRAW_EDGE_LINES
lcProfileEntry("Settings", "GridStuds", 1), // LC_PROFILE_GRID_STUDS
lcProfileEntry("Settings", "GridStudColor", LC_RGBA(64, 64, 64, 192)), // LC_PROFILE_GRID_STUD_COLOR
lcProfileEntry("Settings", "GridLines", 1), // LC_PROFILE_GRID_LINES
lcProfileEntry("Settings", "GridLineSpacing", 5), // LC_PROFILE_GRID_LINE_SPACING
lcProfileEntry("Settings", "GridLineColor", LC_RGBA(0, 0, 0, 255)), // LC_PROFILE_GRID_LINE_COLOR
lcProfileEntry("Settings", "AASamples", 1), // LC_PROFILE_ANTIALIASING_SAMPLES
lcProfileEntry("Settings", "ViewSphereLocation", (int)lcViewSphereLocation::TOP_RIGHT), // LC_PROFILE_VIEW_SPHERE_LOCATION
lcProfileEntry("Settings", "ViewSphereSize", 100), // LC_PROFILE_VIEW_SPHERE_SIZE
lcProfileEntry("Settings", "CheckUpdates", 1), // LC_PROFILE_CHECK_UPDATES
lcProfileEntry("Settings", "ProjectsPath", ""), // LC_PROFILE_PROJECTS_PATH
lcProfileEntry("Settings", "PartsLibrary", ""), // LC_PROFILE_PARTS_LIBRARY
lcProfileEntry("Settings", "Shortcuts"), // LC_PROFILE_KEYBOARD_SHORTCUTS
lcProfileEntry("Settings", "MouseShortcuts", QStringList()), // LC_PROFILE_MOUSE_SHORTCUTS
lcProfileEntry("Settings", "Categories"), // LC_PROFILE_CATEGORIES
lcProfileEntry("Settings", "RecentFile1", ""), // LC_PROFILE_RECENT_FILE1
lcProfileEntry("Settings", "RecentFile2", ""), // LC_PROFILE_RECENT_FILE2
lcProfileEntry("Settings", "RecentFile3", ""), // LC_PROFILE_RECENT_FILE3
lcProfileEntry("Settings", "RecentFile4", ""), // LC_PROFILE_RECENT_FILE4
lcProfileEntry("Settings", "AutosaveInterval", 10), // LC_PROFILE_AUTOSAVE_INTERVAL
lcProfileEntry("Settings", "MouseSensitivity", 11), // LC_PROFILE_MOUSE_SENSITIVITY
lcProfileEntry("Settings", "ImageWidth", 1280), // LC_PROFILE_IMAGE_WIDTH
lcProfileEntry("Settings", "ImageHeight", 720), // LC_PROFILE_IMAGE_HEIGHT
lcProfileEntry("Settings", "ImageExtension", ".png"), // LC_PROFILE_IMAGE_EXTENSION
lcProfileEntry("Settings", "PrintRows", 1), // LC_PROFILE_PRINT_ROWS
lcProfileEntry("Settings", "PrintColumns", 1), // LC_PROFILE_PRINT_COLUMNS
lcProfileEntry("Settings", "PartsListIcons", 64), // LC_PROFILE_PARTS_LIST_ICONS
lcProfileEntry("Settings", "PartsListNames", 0), // LC_PROFILE_PARTS_LIST_NAMES
lcProfileEntry("Settings", "PartsListFixedColor", -1), // LC_PROFILE_PARTS_LIST_FIXED_COLOR
lcProfileEntry("Settings", "PartsListDecorated", 1), // LC_PROFILE_PARTS_LIST_DECORATED
lcProfileEntry("Settings", "PartsListListMode", 0), // LC_PROFILE_PARTS_LIST_LISTMODE
lcProfileEntry("Settings", "CheckUpdates", 1), // LC_PROFILE_CHECK_UPDATES
lcProfileEntry("Settings", "ProjectsPath", ""), // LC_PROFILE_PROJECTS_PATH
lcProfileEntry("Settings", "PartsLibrary", ""), // LC_PROFILE_PARTS_LIBRARY
lcProfileEntry("Settings", "Shortcuts"), // LC_PROFILE_KEYBOARD_SHORTCUTS
lcProfileEntry("Settings", "MouseShortcuts", QStringList()), // LC_PROFILE_MOUSE_SHORTCUTS
lcProfileEntry("Settings", "Categories"), // LC_PROFILE_CATEGORIES
lcProfileEntry("Settings", "RecentFile1", ""), // LC_PROFILE_RECENT_FILE1
lcProfileEntry("Settings", "RecentFile2", ""), // LC_PROFILE_RECENT_FILE2
lcProfileEntry("Settings", "RecentFile3", ""), // LC_PROFILE_RECENT_FILE3
lcProfileEntry("Settings", "RecentFile4", ""), // LC_PROFILE_RECENT_FILE4
lcProfileEntry("Settings", "AutosaveInterval", 10), // LC_PROFILE_AUTOSAVE_INTERVAL
lcProfileEntry("Settings", "MouseSensitivity", 11), // LC_PROFILE_MOUSE_SENSITIVITY
lcProfileEntry("Settings", "ImageWidth", 1280), // LC_PROFILE_IMAGE_WIDTH
lcProfileEntry("Settings", "ImageHeight", 720), // LC_PROFILE_IMAGE_HEIGHT
lcProfileEntry("Settings", "ImageExtension", ".png"), // LC_PROFILE_IMAGE_EXTENSION
lcProfileEntry("Settings", "PrintRows", 1), // LC_PROFILE_PRINT_ROWS
lcProfileEntry("Settings", "PrintColumns", 1), // LC_PROFILE_PRINT_COLUMNS
lcProfileEntry("Settings", "PartsListIcons", 64), // LC_PROFILE_PARTS_LIST_ICONS
lcProfileEntry("Settings", "PartsListNames", 0), // LC_PROFILE_PARTS_LIST_NAMES
lcProfileEntry("Settings", "PartsListFixedColor", -1), // LC_PROFILE_PARTS_LIST_FIXED_COLOR
lcProfileEntry("Settings", "PartsListDecorated", 1), // LC_PROFILE_PARTS_LIST_DECORATED
lcProfileEntry("Settings", "PartsListListMode", 0), // LC_PROFILE_PARTS_LIST_LISTMODE
lcProfileEntry("Defaults", "Author", ""), // LC_PROFILE_DEFAULT_AUTHOR_NAME
lcProfileEntry("Defaults", "FloorColor", LC_RGB(0, 191, 0)), // LC_PROFILE_DEFAULT_FLOOR_COLOR
lcProfileEntry("Defaults", "FloorTexture", ""), // LC_PROFILE_DEFAULT_FLOOR_TEXTURE
lcProfileEntry("Defaults", "AmbientColor", LC_RGB(75, 75, 75)), // LC_PROFILE_DEFAULT_AMBIENT_COLOR
lcProfileEntry("Defaults", "BackgroundType", LC_BACKGROUND_SOLID), // LC_PROFILE_DEFAULT_BACKGROUND_TYPE
lcProfileEntry("Defaults", "BackgroundColor", LC_RGB(255, 255, 255)), // LC_PROFILE_DEFAULT_BACKGROUND_COLOR
lcProfileEntry("Defaults", "GradientColor1", LC_RGB(0, 0, 191)), // LC_PROFILE_DEFAULT_GRADIENT_COLOR1
lcProfileEntry("Defaults", "GradientColor2", LC_RGB(255, 255, 255)), // LC_PROFILE_DEFAULT_GRADIENT_COLOR2
lcProfileEntry("Defaults", "BackgroundTexture", ""), // LC_PROFILE_DEFAULT_BACKGROUND_TEXTURE
lcProfileEntry("Defaults", "BackgroundTile", 0), // LC_PROFILE_DEFAULT_BACKGROUND_TILE
lcProfileEntry("Defaults", "Author", ""), // LC_PROFILE_DEFAULT_AUTHOR_NAME
lcProfileEntry("Defaults", "FloorColor", LC_RGB(0, 191, 0)), // LC_PROFILE_DEFAULT_FLOOR_COLOR
lcProfileEntry("Defaults", "FloorTexture", ""), // LC_PROFILE_DEFAULT_FLOOR_TEXTURE
lcProfileEntry("Defaults", "AmbientColor", LC_RGB(75, 75, 75)), // LC_PROFILE_DEFAULT_AMBIENT_COLOR
lcProfileEntry("Defaults", "BackgroundType", LC_BACKGROUND_SOLID), // LC_PROFILE_DEFAULT_BACKGROUND_TYPE
lcProfileEntry("Defaults", "BackgroundColor", LC_RGB(255, 255, 255)), // LC_PROFILE_DEFAULT_BACKGROUND_COLOR
lcProfileEntry("Defaults", "GradientColor1", LC_RGB(0, 0, 191)), // LC_PROFILE_DEFAULT_GRADIENT_COLOR1
lcProfileEntry("Defaults", "GradientColor2", LC_RGB(255, 255, 255)), // LC_PROFILE_DEFAULT_GRADIENT_COLOR2
lcProfileEntry("Defaults", "BackgroundTexture", ""), // LC_PROFILE_DEFAULT_BACKGROUND_TEXTURE
lcProfileEntry("Defaults", "BackgroundTile", 0), // LC_PROFILE_DEFAULT_BACKGROUND_TILE
lcProfileEntry("HTML", "Options", LC_HTML_SINGLEPAGE), // LC_PROFILE_HTML_OPTIONS
lcProfileEntry("HTML", "ImageOptions", LC_IMAGE_TRANSPARENT), // LC_PROFILE_HTML_IMAGE_OPTIONS
lcProfileEntry("HTML", "ImageWidth", 640), // LC_PROFILE_HTML_IMAGE_WIDTH
lcProfileEntry("HTML", "ImageHeight", 480), // LC_PROFILE_HTML_IMAGE_HEIGHT
lcProfileEntry("HTML", "PartsColor", 16), // LC_PROFILE_HTML_PARTS_COLOR
lcProfileEntry("HTML", "PartsWidth", 128), // LC_PROFILE_HTML_PARTS_WIDTH
lcProfileEntry("HTML", "PartsHeight", 128), // LC_PROFILE_HTML_PARTS_HEIGHT
lcProfileEntry("HTML", "Options", LC_HTML_SINGLEPAGE), // LC_PROFILE_HTML_OPTIONS
lcProfileEntry("HTML", "ImageOptions", LC_IMAGE_TRANSPARENT), // LC_PROFILE_HTML_IMAGE_OPTIONS
lcProfileEntry("HTML", "ImageWidth", 640), // LC_PROFILE_HTML_IMAGE_WIDTH
lcProfileEntry("HTML", "ImageHeight", 480), // LC_PROFILE_HTML_IMAGE_HEIGHT
lcProfileEntry("HTML", "PartsColor", 16), // LC_PROFILE_HTML_PARTS_COLOR
lcProfileEntry("HTML", "PartsWidth", 128), // LC_PROFILE_HTML_PARTS_WIDTH
lcProfileEntry("HTML", "PartsHeight", 128), // LC_PROFILE_HTML_PARTS_HEIGHT
lcProfileEntry("POVRay", "Path", "/usr/bin/povray"), // LC_PROFILE_POVRAY_PATH
lcProfileEntry("POVRay", "LGEOPath", ""), // LC_PROFILE_POVRAY_LGEO_PATH
lcProfileEntry("POVRay", "Width", 1280), // LC_PROFILE_POVRAY_WIDTH
lcProfileEntry("POVRay", "Height", 720) // LC_PROFILE_POVRAY_HEIGHT
lcProfileEntry("POVRay", "Path", "/usr/bin/povray"), // LC_PROFILE_POVRAY_PATH
lcProfileEntry("POVRay", "LGEOPath", ""), // LC_PROFILE_POVRAY_LGEO_PATH
lcProfileEntry("POVRay", "Width", 1280), // LC_PROFILE_POVRAY_WIDTH
lcProfileEntry("POVRay", "Height", 720) // LC_PROFILE_POVRAY_HEIGHT
};
void lcRemoveProfileKey(LC_PROFILE_KEY Key)

View file

@ -14,8 +14,8 @@ enum LC_PROFILE_KEY
LC_PROFILE_GRID_LINE_SPACING,
LC_PROFILE_GRID_LINE_COLOR,
LC_PROFILE_ANTIALIASING_SAMPLES,
LC_PROFILE_VIEW_CUBE_LOCATION,
LC_PROFILE_VIEW_CUBE_SIZE,
LC_PROFILE_VIEW_SPHERE_LOCATION,
LC_PROFILE_VIEW_SPHERE_SIZE,
LC_PROFILE_CHECK_UPDATES,
LC_PROFILE_PROJECTS_PATH,

View file

@ -195,6 +195,13 @@ void lcTexture::SetImage(Image* Image, int Flags)
Load(Flags);
}
void lcTexture::SetImage(std::vector<Image>&& Images, int Flags)
{
mImages = std::move(Images);
Load(Flags);
}
void lcTexture::Upload(lcContext* Context)
{
mWidth = mImages[0].mWidth;
@ -213,15 +220,33 @@ void lcTexture::Upload(lcContext* Context)
int FilterIndex = FilterFlags >> LC_TEXTURE_FILTER_SHIFT;
int MipIndex = mFlags & LC_TEXTURE_MIPMAPS ? 0 : 1;
Context->BindTexture2D(mTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (mFlags & LC_TEXTURE_WRAPU) ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (mFlags & LC_TEXTURE_WRAPV) ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filters[MipIndex][FilterIndex]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filters[1][FilterIndex]);
int Faces, Target;
if ((mFlags & LC_TEXTURE_CUBEMAP) == 0)
{
Faces = 1;
Target = GL_TEXTURE_2D;
Context->BindTexture2D(mTexture);
}
else
{
Faces = 6;
Target = GL_TEXTURE_CUBE_MAP;
Context->BindTextureCubeMap(mTexture);
}
glTexParameteri(Target, GL_TEXTURE_WRAP_S, (mFlags & LC_TEXTURE_WRAPU) ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(Target, GL_TEXTURE_WRAP_T, (mFlags & LC_TEXTURE_WRAPV) ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, Filters[MipIndex][FilterIndex]);
glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, Filters[1][FilterIndex]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
if (gSupportsAnisotropic && FilterFlags == LC_TEXTURE_ANISOTROPIC)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, lcMin(4.0f, gMaxAnisotropy));
glTexParameterf(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, lcMin(4.0f, gMaxAnisotropy));
int Format;
switch (mImages[0].mFormat)
@ -244,41 +269,58 @@ void lcTexture::Upload(lcContext* Context)
break;
}
void* Data = mImages[0].mData;
glTexImage2D(GL_TEXTURE_2D, 0, Format, mWidth, mHeight, 0, Format, GL_UNSIGNED_BYTE, Data);
int CurrentImage = 0;
if (mFlags & LC_TEXTURE_CUBEMAP)
Target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
if (mFlags & LC_TEXTURE_MIPMAPS || FilterFlags >= LC_TEXTURE_BILINEAR)
for (int FaceIdx = 0; FaceIdx < Faces; FaceIdx++)
{
int Width = mWidth;
int Height = mHeight;
int Components = mImages[0].GetBPP();
void* Data = mImages[CurrentImage].mData;
glTexImage2D(Target, 0, Format, mWidth, mHeight, 0, Format, GL_UNSIGNED_BYTE, Data);
for (int Level = 1; ((Width != 1) || (Height != 1)); Level++)
if (mFlags & LC_TEXTURE_MIPMAPS || FilterFlags >= LC_TEXTURE_BILINEAR)
{
int RowStride = Width * Components;
int Width = mWidth;
int Height = mHeight;
int Components = mImages[CurrentImage].GetBPP();
Width = lcMax(1, Width >> 1);
Height = lcMax(1, Height >> 1);
if (mImages.size() == 1)
for (int Level = 1; ((Width != 1) || (Height != 1)); Level++)
{
GLubyte *Out, *In;
int RowStride = Width * Components;
In = Out = (GLubyte*)Data;
Width = lcMax(1, Width >> 1);
Height = lcMax(1, Height >> 1);
for (int y = 0; y < Height; y++, In += RowStride)
for (int x = 0; x < Width; x++, Out += Components, In += 2 * Components)
for (int c = 0; c < Components; c++)
Out[c] = (In[c] + In[c + Components] + In[RowStride] + In[c + RowStride + Components]) / 4;
if (mImages.size() == Faces)
{
GLubyte *Out, *In;
In = Out = (GLubyte*)Data;
for (int y = 0; y < Height; y++, In += RowStride)
for (int x = 0; x < Width; x++, Out += Components, In += 2 * Components)
for (int c = 0; c < Components; c++)
Out[c] = (In[c] + In[c + Components] + In[RowStride] + In[c + RowStride + Components]) / 4;
}
else
Data = mImages[++CurrentImage].mData;
glTexImage2D(Target, Level, Format, Width, Height, 0, Format, GL_UNSIGNED_BYTE, Data);
}
else
Data = mImages[Level].mData;
glTexImage2D(GL_TEXTURE_2D, Level, Format, Width, Height, 0, Format, GL_UNSIGNED_BYTE, Data);
if (mImages.size() == Faces)
CurrentImage++;
}
else
CurrentImage++;
Target++;
}
Context->UnbindTexture2D(mTexture);
if ((mFlags & LC_TEXTURE_CUBEMAP) == 0)
Context->UnbindTexture2D(mTexture);
else
Context->UnbindTextureCubeMap(mTexture);
}
bool lcTexture::Load(int Flags)

View file

@ -3,6 +3,7 @@
#define LC_TEXTURE_WRAPU 0x01
#define LC_TEXTURE_WRAPV 0x02
#define LC_TEXTURE_MIPMAPS 0x04
#define LC_TEXTURE_CUBEMAP 0x08
#define LC_TEXTURE_POINT 0x00
#define LC_TEXTURE_LINEAR 0x10
@ -27,6 +28,7 @@ public:
bool Load(const QString& FileName, int Flags = 0);
bool Load(lcMemFile& File, int Flags = 0);
void SetImage(Image* Image, int Flags = 0);
void SetImage(std::vector<Image>&& Images, int Flags = 0);
void Upload(lcContext* Context);
void Unload();

View file

@ -1,357 +0,0 @@
#include "lc_global.h"
#include "lc_viewcube.h"
#include "view.h"
#include "lc_context.h"
#include "lc_stringcache.h"
#include "lc_application.h"
//todo: move these
const float BoxSize = 10.0f;
const float EdgeSize = BoxSize * 1.0f / 3.0f;
const float CenterSize = BoxSize * 2.0f / 3.0f;
lcViewCube::lcViewCube(View* View)
: mView(View)
{
mMouseDown = false;
}
lcMatrix44 lcViewCube::GetViewMatrix() const
{
lcMatrix44 ViewMatrix = mView->mCamera->mWorldView;
ViewMatrix.SetTranslation(lcVector3(0, 0, 0));
return ViewMatrix;
}
lcMatrix44 lcViewCube::GetProjectionMatrix() const
{
return lcMatrix44Ortho(-BoxSize * 2, BoxSize * 2, -BoxSize * 2, BoxSize * 2, -50, 50);
}
void lcViewCube::Draw()
{
const lcPreferences& Preferences = lcGetPreferences();
lcViewCubeLocation Location = Preferences.mViewCubeLocation;
if (Location == lcViewCubeLocation::DISABLED)
return;
lcContext* Context = mView->mContext;
int Width = mView->mWidth;
int Height = mView->mHeight;
int ViewportSize = Preferences.mViewCubeSize;
int Left = (Location == lcViewCubeLocation::BOTTOM_LEFT || Location == lcViewCubeLocation::TOP_LEFT) ? 0 : Width - ViewportSize;
int Bottom = (Location == lcViewCubeLocation::BOTTOM_LEFT || Location == lcViewCubeLocation::BOTTOM_RIGHT) ? 0 : Height - ViewportSize;
Context->SetViewport(Left, Bottom, ViewportSize, ViewportSize);
const lcVector3 BoxVerts[56] =
{
lcVector3( BoxSize, -CenterSize, -CenterSize), lcVector3( BoxSize, CenterSize, -CenterSize), lcVector3( BoxSize, -CenterSize, CenterSize), lcVector3( BoxSize, CenterSize, CenterSize),
lcVector3(-BoxSize, -CenterSize, -CenterSize), lcVector3(-BoxSize, CenterSize, -CenterSize), lcVector3(-BoxSize, -CenterSize, CenterSize), lcVector3(-BoxSize, CenterSize, CenterSize),
lcVector3(-CenterSize, BoxSize, -CenterSize), lcVector3(CenterSize, BoxSize, -CenterSize), lcVector3(-CenterSize, BoxSize, CenterSize), lcVector3(CenterSize, BoxSize, CenterSize),
lcVector3(-CenterSize, -BoxSize, -CenterSize), lcVector3(CenterSize, -BoxSize, -CenterSize), lcVector3(-CenterSize, -BoxSize, CenterSize), lcVector3(CenterSize, -BoxSize, CenterSize),
lcVector3(-CenterSize, -CenterSize, BoxSize), lcVector3(CenterSize, -CenterSize, BoxSize), lcVector3(-CenterSize, CenterSize, BoxSize), lcVector3(CenterSize, CenterSize, BoxSize),
lcVector3(-CenterSize, -CenterSize, -BoxSize), lcVector3(CenterSize, -CenterSize, -BoxSize), lcVector3(-CenterSize, CenterSize, -BoxSize), lcVector3(CenterSize, CenterSize, -BoxSize),
lcVector3( BoxSize, -BoxSize, -CenterSize), lcVector3( BoxSize, BoxSize, -CenterSize), lcVector3( BoxSize, -BoxSize, CenterSize), lcVector3( BoxSize, BoxSize, CenterSize),
lcVector3(-BoxSize, -BoxSize, -CenterSize), lcVector3(-BoxSize, BoxSize, -CenterSize), lcVector3(-BoxSize, -BoxSize, CenterSize), lcVector3(-BoxSize, BoxSize, CenterSize),
lcVector3(-CenterSize, BoxSize, -BoxSize), lcVector3(CenterSize, BoxSize, -BoxSize), lcVector3(-CenterSize, BoxSize, BoxSize), lcVector3(CenterSize, BoxSize, BoxSize),
lcVector3(-CenterSize, -BoxSize, -BoxSize), lcVector3(CenterSize, -BoxSize, -BoxSize), lcVector3(-CenterSize, -BoxSize, BoxSize), lcVector3(CenterSize, -BoxSize, BoxSize),
lcVector3(-BoxSize, -CenterSize, BoxSize), lcVector3(BoxSize, -CenterSize, BoxSize), lcVector3(-BoxSize, CenterSize, BoxSize), lcVector3(BoxSize, CenterSize, BoxSize),
lcVector3(-BoxSize, -CenterSize, -BoxSize), lcVector3(BoxSize, -CenterSize, -BoxSize), lcVector3(-BoxSize, CenterSize, -BoxSize), lcVector3(BoxSize, CenterSize, -BoxSize),
lcVector3( BoxSize, -BoxSize, -BoxSize), lcVector3( BoxSize, BoxSize, -BoxSize), lcVector3( BoxSize, -BoxSize, BoxSize), lcVector3( BoxSize, BoxSize, BoxSize),
lcVector3(-BoxSize, -BoxSize, -BoxSize), lcVector3(-BoxSize, BoxSize, -BoxSize), lcVector3(-BoxSize, -BoxSize, BoxSize), lcVector3(-BoxSize, BoxSize, BoxSize)
};
const GLushort BoxIndices[36 + 144 + 144 + 24] =
{
0, 1, 2, 3, 2, 1, 5, 6, 7, 6, 5, 4,
10, 9, 8, 9, 10, 11, 13, 15, 14, 12, 13, 14,
16, 17, 18, 19, 18, 17, 21, 22, 23, 22, 21, 20,
25, 3, 1, 3, 25, 27, 9, 11, 25, 27, 25, 11,
0, 2, 24, 26, 24, 2, 24, 15, 13, 15, 24, 26,
2, 3, 43, 2, 43, 41, 19, 17, 43, 41, 43, 17,
47, 1, 0, 45, 47, 0, 47, 21, 23, 21, 47, 45,
5, 7, 29, 31, 29, 7, 10, 8, 31, 8, 29, 31,
28, 6, 4, 6, 28, 30, 12, 14, 28, 30, 28, 14,
42, 7, 6, 40, 42, 6, 42, 16, 18, 16, 42, 40,
4, 5, 46, 4, 46, 44, 22, 20, 46, 44, 46, 20,
34, 11, 10, 34, 35, 11, 35, 34, 19, 18, 19, 34,
8, 9, 32, 9, 33, 32, 23, 32, 33, 32, 23, 22,
14, 15, 38, 15, 39, 38, 17, 38, 39, 38, 17, 16,
36, 13, 12, 36, 37, 13, 37, 36, 21, 20, 21, 36,
51, 3, 27, 43, 3, 51, 27, 11, 51, 51, 11, 35, 35, 19, 51, 51, 19, 43,
25, 1, 49, 49, 1, 47, 49, 9, 25, 33, 9, 49, 49, 23, 33, 47, 23, 49,
26, 2, 50, 50, 2, 41, 50, 15, 26, 39, 15, 50, 50, 17, 39, 41, 17, 50,
48, 0, 24, 45, 0, 48, 24, 13, 48, 48, 13, 37, 37, 21, 48, 48, 21, 45,
31, 7, 55, 55, 7, 42, 55, 10, 31, 34, 10, 55, 55, 18, 34, 42, 18, 55,
53, 5, 29, 46, 5, 53, 29, 8, 53, 53, 8, 32, 32, 22, 53, 53, 22, 46,
54, 6, 30, 40, 6, 54, 30, 14, 54, 54, 14, 38, 38, 16, 54, 54, 16, 40,
28, 4, 52, 52, 4, 44, 52, 12, 28, 36, 12, 52, 52, 20, 36, 44, 20, 52,
48, 52, 49, 53, 50, 54, 51, 55, 48, 49, 50, 51, 52, 53, 54, 55, 48, 50, 49, 51, 52, 54, 53, 55
};
Context->SetMaterial(LC_MATERIAL_UNLIT_COLOR);
Context->SetWorldMatrix(lcMatrix44Identity());
Context->SetViewMatrix(GetViewMatrix());
Context->SetProjectionMatrix(GetProjectionMatrix());
Context->SetVertexBufferPointer(BoxVerts);
Context->SetVertexFormatPosition(3);
Context->SetIndexBufferPointer(BoxIndices);
glDepthFunc(GL_ALWAYS);
glEnable(GL_CULL_FACE);
Context->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 36 + 144 + 144, GL_UNSIGNED_SHORT, 0);
int IntersectionType = mIntersectionFlags.count();
if (IntersectionType == 1)
{
for (int FlagIdx = 0; FlagIdx < 6; FlagIdx++)
{
if (mIntersectionFlags.test(FlagIdx))
{
Context->SetColor(1.0f, 0.0f, 0.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, FlagIdx * 6 * 2);
break;
}
}
}
else if (IntersectionType == 2)
{
int First;
if (mIntersectionFlags.test(0))
{
if (mIntersectionFlags.test(2))
First = 36;
else if (mIntersectionFlags.test(3))
First = 36 + 12;
else if (mIntersectionFlags.test(4))
First = 36 + 24;
else
First = 36 + 36;
}
else if (mIntersectionFlags.test(1))
{
if (mIntersectionFlags.test(2))
First = 36 + 48;
else if (mIntersectionFlags.test(3))
First = 36 + 48 + 12;
else if (mIntersectionFlags.test(4))
First = 36 + 48 + 24;
else
First = 36 + 48 + 36;
}
else if (mIntersectionFlags.test(2))
{
if (mIntersectionFlags.test(4))
First = 36 + 96;
else
First = 36 + 96 + 12;
}
else
{
if (mIntersectionFlags.test(4))
First = 36 + 96 + 24;
else
First = 36 + 96 + 36;
}
Context->SetColor(1.0f, 0.0f, 0.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 12, GL_UNSIGNED_SHORT, First * 2);
}
else if (IntersectionType == 3)
{
int First = 36 + 144;
if (mIntersectionFlags.test(1))
First += 72;
if (mIntersectionFlags.test(3))
First += 36;
if (mIntersectionFlags.test(5))
First += 18;
Context->SetColor(1.0f, 0.0f, 0.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_TRIANGLES, 18, GL_UNSIGNED_SHORT, First * 2);
}
glDepthFunc(GL_LEQUAL);
Context->SetColor(0.0f, 0.0f, 0.0f, 1.0f);
Context->DrawIndexedPrimitives(GL_LINES, 24, GL_UNSIGNED_SHORT, (36 + 144 + 144) * 2);
Context->SetMaterial(LC_MATERIAL_UNLIT_TEXTURE_MODULATE);
glEnable(GL_BLEND);
glDepthFunc(GL_ALWAYS);
QStringList ViewNames =
{
QT_TRANSLATE_NOOP("ViewName", "Front"),
QT_TRANSLATE_NOOP("ViewName", "Back"),
QT_TRANSLATE_NOOP("ViewName", "Top"),
QT_TRANSLATE_NOOP("ViewName", "Bottom"),
QT_TRANSLATE_NOOP("ViewName", "Left"),
QT_TRANSLATE_NOOP("ViewName", "Right")
};
int MaxText = 0;
for (int FaceIdx = 0; FaceIdx < 6; FaceIdx++)
{
int Width, Height;
gStringCache.GetStringDimensions(&Width, &Height, ViewNames[FaceIdx]);
if (Width > MaxText)
MaxText = Width;
if (Height > MaxText)
MaxText = Height;
}
float Scale = BoxSize * 4.0f / 3.0f / (float)MaxText;
lcMatrix44 ViewMatrices[6] =
{
lcMatrix44(lcVector4(Scale, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, Scale, 0.0f), lcVector4(0.0f, 1.0f, 0.0f, 0.0f), lcVector4(0.0f, -BoxSize - 0.01f, 0.0f, 1.0f)),
lcMatrix44(lcVector4(-Scale, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, Scale, 0.0f), lcVector4(0.0f, 1.0f, 0.0f, 0.0f), lcVector4(0.0f, BoxSize + 0.01f, 0.0f, 1.0f)),
lcMatrix44(lcVector4(Scale, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, Scale, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 0.0f, BoxSize + 0.01f, 1.0f)),
lcMatrix44(lcVector4(Scale, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, -Scale, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 0.0f, -BoxSize - 0.01f, 1.0f)),
lcMatrix44(lcVector4(0.0f, Scale, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, Scale, 0.0f), lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4(BoxSize + 0.01f, 0.0f, 0.0f, 1.0f)),
lcMatrix44(lcVector4(0.0f, -Scale, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, Scale, 0.0f), lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4(-BoxSize - 0.01f, 0.0f, 0.0f, 1.0f))
};
gStringCache.CacheStrings(ViewNames); // todo: precache earlier because the texture only gets uploaded on the next frame
gStringCache.DrawStrings(Context, ViewMatrices, ViewNames);
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL);
Context->SetViewport(0, 0, Width, Height);
}
bool lcViewCube::OnLeftButtonDown()
{
const lcPreferences& Preferences = lcGetPreferences();
if (Preferences.mViewCubeLocation == lcViewCubeLocation::DISABLED)
return false;
mIntersectionFlags = GetIntersectionFlags(mIntersection);
if (!mIntersectionFlags.any())
return false;
mMouseDownX = mView->mInputState.x;
mMouseDownY = mView->mInputState.y;
mMouseDown = true;
return true;
}
bool lcViewCube::OnLeftButtonUp()
{
const lcPreferences& Preferences = lcGetPreferences();
if (Preferences.mViewCubeLocation == lcViewCubeLocation::DISABLED)
return false;
if (!mMouseDown)
return false;
mMouseDown = false;
if (!mIntersectionFlags.any())
return false;
lcVector3 Position(0.0f, 0.0f, 0.0f);
for (int AxisIdx = 0; AxisIdx < 3; AxisIdx++)
{
if (mIntersectionFlags.test(AxisIdx * 2))
Position[AxisIdx] = 1250.0f;
else if (mIntersectionFlags.test(AxisIdx * 2 + 1))
Position[AxisIdx] = -1250.0f;
}
mView->SetViewpoint(Position);
return true;
}
bool lcViewCube::OnMouseMove()
{
const lcPreferences& Preferences = lcGetPreferences();
lcViewCubeLocation Location = Preferences.mViewCubeLocation;
if (Location == lcViewCubeLocation::DISABLED)
return false;
if (IsDragging())
{
mIntersectionFlags.reset();
mView->StartOrbitTracking();
return true;
}
if (mView->IsTracking())
return false;
std::bitset<6> IntersectionFlags = GetIntersectionFlags(mIntersection);
if (IntersectionFlags != mIntersectionFlags)
{
mIntersectionFlags = IntersectionFlags;
mView->Redraw();
}
return mIntersectionFlags.any();
}
bool lcViewCube::IsDragging() const
{
return mMouseDown && (qAbs(mMouseDownX - mView->mInputState.x) > 3 || qAbs(mMouseDownY - mView->mInputState.y) > 3);
}
std::bitset<6> lcViewCube::GetIntersectionFlags(lcVector3& Intersection) const
{
const lcPreferences& Preferences = lcGetPreferences();
lcViewCubeLocation Location = Preferences.mViewCubeLocation;
int Width = mView->mWidth;
int Height = mView->mHeight;
int ViewportSize = Preferences.mViewCubeSize;
int Left = (Location == lcViewCubeLocation::BOTTOM_LEFT || Location == lcViewCubeLocation::TOP_LEFT) ? 0 : Width - ViewportSize;
int Bottom = (Location == lcViewCubeLocation::BOTTOM_LEFT || Location == lcViewCubeLocation::BOTTOM_RIGHT) ? 0 : Height - ViewportSize;
int x = mView->mInputState.x - Left;
int y = mView->mInputState.y - Bottom;
std::bitset<6> IntersectionFlags;
if (x < 0 || x > Width || y < 0 || y > Height)
return IntersectionFlags;
lcVector3 StartEnd[2] = { lcVector3(x, y, 0), lcVector3(x, y, 1) };
const int Viewport[4] = { 0, 0, ViewportSize, ViewportSize };
lcUnprojectPoints(StartEnd, 2, GetViewMatrix(), GetProjectionMatrix(), Viewport);
float Distance;
if (lcBoundingBoxRayIntersectDistance(lcVector3(-BoxSize, -BoxSize, -BoxSize), lcVector3(BoxSize, BoxSize, BoxSize), StartEnd[0], StartEnd[1], &Distance, &Intersection))
{
for (int AxisIdx = 0; AxisIdx < 3; AxisIdx++)
{
if (mIntersection[AxisIdx] > BoxSize * 2 / 3)
IntersectionFlags.set(2 * AxisIdx);
else if (mIntersection[AxisIdx] < -BoxSize * 2 / 3)
IntersectionFlags.set(2 * AxisIdx + 1);
}
}
return IntersectionFlags;
}

328
common/lc_viewsphere.cpp Normal file
View file

@ -0,0 +1,328 @@
#include "lc_global.h"
#include "lc_viewsphere.h"
#include "view.h"
#include "lc_context.h"
#include "lc_stringcache.h"
#include "lc_application.h"
#include "image.h"
#include "lc_texture.h"
lcTexture* lcViewSphere::mTexture;
//todo: move these
const float BoxSize = 10.0f;
lcViewSphere::lcViewSphere(View* View)
: mView(View)
{
mMouseDown = false;
}
lcMatrix44 lcViewSphere::GetViewMatrix() const
{
lcMatrix44 ViewMatrix = mView->mCamera->mWorldView;
ViewMatrix.SetTranslation(lcVector3(0, 0, 0));
return ViewMatrix;
}
lcMatrix44 lcViewSphere::GetProjectionMatrix() const
{
return lcMatrix44Ortho(-BoxSize * 2, BoxSize * 2, -BoxSize * 2, BoxSize * 2, -50, 50);
}
void lcViewSphere::CreateResources()
{
const int ImageSize = 128;
mTexture = new lcTexture();
const QString ViewNames[6] =
{
QT_TRANSLATE_NOOP("ViewName", "Left"), QT_TRANSLATE_NOOP("ViewName", "Right"), QT_TRANSLATE_NOOP("ViewName", "Back"),
QT_TRANSLATE_NOOP("ViewName", "Front"), QT_TRANSLATE_NOOP("ViewName", "Top"), QT_TRANSLATE_NOOP("ViewName", "Bottom")
};
const QTransform ViewTransforms[6] =
{
QTransform(0, 1, 1, 0, 0, 0), QTransform(0, -1, -1, 0, ImageSize, ImageSize), QTransform(-1, 0, 0, 1, ImageSize, 0),
QTransform(1, 0, 0, -1, 0, ImageSize), QTransform(1, 0, 0, -1, 0, ImageSize), QTransform(-1, 0, 0, 1, ImageSize, 0)
};
QImage PainterImage(ImageSize, ImageSize, QImage::Format_ARGB32);
QPainter Painter;
QFont Font("Helvetica", 20);
std::vector<Image> Images;
for (int ViewIdx = 0; ViewIdx < 6; ViewIdx++)
{
Image TextureImage;
TextureImage.Allocate(ImageSize, ImageSize, LC_PIXEL_FORMAT_L8A8);
Painter.begin(&PainterImage);
Painter.fillRect(0, 0, PainterImage.width(), PainterImage.height(), QColor(0, 0, 0));
Painter.setBrush(QColor(255, 255, 255));
Painter.setPen(QColor(255, 255, 255));
Painter.setFont(Font);
Painter.setTransform(ViewTransforms[ViewIdx]);
Painter.drawText(0, 0, PainterImage.width(), PainterImage.height(), Qt::AlignCenter, ViewNames[ViewIdx]);
Painter.end();
for (int y = 0; y < ImageSize; y++)
{
unsigned char* Dest = TextureImage.mData + ((ImageSize - y - 1) * TextureImage.mWidth) * 2;
for (int x = 0; x < ImageSize; x++)
{
*Dest = 0;
*(Dest + 1) = qRed(PainterImage.pixel(x, y));
Dest += 2;
}
}
Images.emplace_back(std::move(TextureImage));
}
mTexture->SetImage(std::move(Images), LC_TEXTURE_CUBEMAP | LC_TEXTURE_LINEAR);
}
void lcViewSphere::DestroyResources()
{
delete mTexture;
mTexture = nullptr;
}
const int Subdivisions = 9;
lcVector3 Verts[(Subdivisions + 1) * (Subdivisions + 1) * 6];
const int NumIndices = Subdivisions * Subdivisions * 6 * 6;
GLushort Indices[NumIndices];
void lcViewSphere::Draw()
{
const lcPreferences& Preferences = lcGetPreferences();
lcViewSphereLocation Location = Preferences.mViewSphereLocation;
if (Location == lcViewSphereLocation::DISABLED)
return;
lcContext* Context = mView->mContext;
int Width = mView->mWidth;
int Height = mView->mHeight;
int ViewportSize = Preferences.mViewSphereSize;
int Left = (Location == lcViewSphereLocation::BOTTOM_LEFT || Location == lcViewSphereLocation::TOP_LEFT) ? 0 : Width - ViewportSize;
int Bottom = (Location == lcViewSphereLocation::BOTTOM_LEFT || Location == lcViewSphereLocation::BOTTOM_RIGHT) ? 0 : Height - ViewportSize;
Context->SetViewport(Left, Bottom, ViewportSize, ViewportSize);
Context->SetMaterial(LC_MATERIAL_UNLIT_VIEW_SPHERE);
Context->BindTextureCubeMap(mTexture->mTexture);
Context->SetWorldMatrix(lcMatrix44Identity());
Context->SetViewMatrix(GetViewMatrix());
Context->SetProjectionMatrix(GetProjectionMatrix());
glDepthFunc(GL_ALWAYS);
glEnable(GL_CULL_FACE);
{
lcMatrix44 Transforms[6] =
{
lcMatrix44(lcVector4( 0.0f, 1.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4( 1.0f, 0.0f, 0.0f, 1.0f)),
lcMatrix44(lcVector4( 0.0f, -1.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(1.0f, 0.0f, 0.0f, 0.0f), lcVector4(-1.0f, 0.0f, 0.0f, 1.0f)),
lcMatrix44(lcVector4(-1.0f, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 1.0f, 0.0f, 0.0f), lcVector4( 0.0f, 1.0f, 0.0f, 1.0f)),
lcMatrix44(lcVector4( 1.0f, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4(0.0f, 1.0f, 0.0f, 0.0f), lcVector4( 0.0f, -1.0f, 0.0f, 1.0f)),
lcMatrix44(lcVector4( 1.0f, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, 1.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4( 0.0f, 0.0f, 1.0f, 1.0f)),
lcMatrix44(lcVector4( 1.0f, 0.0f, 0.0f, 0.0f), lcVector4(0.0f, -1.0f, 0.0f, 0.0f), lcVector4(0.0f, 0.0f, 1.0f, 0.0f), lcVector4( 0.0f, 0.0f, -1.0f, 1.0f)),
};
const float Step = 2.0f / Subdivisions;
lcVector3* CurVert = Verts;
for (int FaceIdx = 0; FaceIdx < 6; FaceIdx++)
{
for (int y = 0; y <= Subdivisions; y++)
{
for (int x = 0; x <= Subdivisions; x++)
{
lcVector3 Vert = lcMul31(lcVector3(Step * x - 1.0f, Step * y - 1.0f, 0.0f), Transforms[FaceIdx]);
lcVector3 Vert2 = Vert * Vert;
*CurVert++ = lcVector3(Vert.x * std::sqrt(1.0 - 0.5 * (Vert2.y + Vert2.z) + Vert2.y * Vert2.z / 3.0),
Vert.y * std::sqrt(1.0 - 0.5 * (Vert2.z + Vert2.x) + Vert2.z * Vert2.x / 3.0),
Vert.z * std::sqrt(1.0 - 0.5 * (Vert2.x + Vert2.y) + Vert2.x * Vert2.y / 3.0)
) * BoxSize;
}
}
}
GLushort* CurIndex = Indices;
for (int FaceIdx = 0; FaceIdx < 6; FaceIdx++)
{
const int FaceBase = FaceIdx * (Subdivisions + 1) * (Subdivisions + 1);
for (int y = 0; y < Subdivisions; y++)
{
int RowBase = FaceBase + (Subdivisions + 1) * y;
for (int x = 0; x < Subdivisions; x++)
{
*CurIndex++ = RowBase + x;
*CurIndex++ = RowBase + x + 1;
*CurIndex++ = RowBase + x + (Subdivisions + 1);
*CurIndex++ = RowBase + x + 1;
*CurIndex++ = RowBase + x + 1 + (Subdivisions + 1);
*CurIndex++ = RowBase + x + (Subdivisions + 1);
}
}
}
Context->SetVertexBufferPointer(Verts);
Context->SetVertexFormatPosition(3);
Context->SetIndexBufferPointer(Indices);
Context->SetColor(1.0f, 1.0f, 1.0f, 1.0f);
Context->SetHighlightColor(lcVector4(0.0f, 0.0f, 0.0f, 1.0f));
Context->DrawIndexedPrimitives(GL_TRIANGLES, NumIndices, GL_UNSIGNED_SHORT, 0);
int IntersectionType = mIntersectionFlags.count();
if (IntersectionType == 1)
{
for (int FlagIdx = 0; FlagIdx < 6; FlagIdx++)
{
if (mIntersectionFlags.test(FlagIdx))
{
int FaceBase = FlagIdx * (Subdivisions) * (Subdivisions) * 6;
Context->SetHighlightColor(lcVector4(1.0, 0, 0, 1.0));
Context->DrawIndexedPrimitives(GL_TRIANGLES, Subdivisions * Subdivisions * 6, GL_UNSIGNED_SHORT, FaceBase * sizeof(GLushort));
break;
}
}
}
}
glDisable(GL_CULL_FACE);
glDepthFunc(GL_LEQUAL);
Context->SetViewport(0, 0, Width, Height);
}
bool lcViewSphere::OnLeftButtonDown()
{
const lcPreferences& Preferences = lcGetPreferences();
if (Preferences.mViewSphereLocation == lcViewSphereLocation::DISABLED)
return false;
mIntersectionFlags = GetIntersectionFlags(mIntersection);
if (!mIntersectionFlags.any())
return false;
mMouseDownX = mView->mInputState.x;
mMouseDownY = mView->mInputState.y;
mMouseDown = true;
return true;
}
bool lcViewSphere::OnLeftButtonUp()
{
const lcPreferences& Preferences = lcGetPreferences();
if (Preferences.mViewSphereLocation == lcViewSphereLocation::DISABLED)
return false;
if (!mMouseDown)
return false;
mMouseDown = false;
if (!mIntersectionFlags.any())
return false;
lcVector3 Position(0.0f, 0.0f, 0.0f);
for (int AxisIdx = 0; AxisIdx < 3; AxisIdx++)
{
if (mIntersectionFlags.test(AxisIdx * 2))
Position[AxisIdx] = 1250.0f;
else if (mIntersectionFlags.test(AxisIdx * 2 + 1))
Position[AxisIdx] = -1250.0f;
}
mView->SetViewpoint(Position);
return true;
}
bool lcViewSphere::OnMouseMove()
{
const lcPreferences& Preferences = lcGetPreferences();
lcViewSphereLocation Location = Preferences.mViewSphereLocation;
if (Location == lcViewSphereLocation::DISABLED)
return false;
if (IsDragging())
{
mIntersectionFlags.reset();
mView->StartOrbitTracking();
return true;
}
if (mView->IsTracking())
return false;
std::bitset<6> IntersectionFlags = GetIntersectionFlags(mIntersection);
if (IntersectionFlags != mIntersectionFlags)
{
mIntersectionFlags = IntersectionFlags;
mView->Redraw();
}
return mIntersectionFlags.any();
}
bool lcViewSphere::IsDragging() const
{
return mMouseDown && (qAbs(mMouseDownX - mView->mInputState.x) > 3 || qAbs(mMouseDownY - mView->mInputState.y) > 3);
}
std::bitset<6> lcViewSphere::GetIntersectionFlags(lcVector3& Intersection) const
{
const lcPreferences& Preferences = lcGetPreferences();
lcViewSphereLocation Location = Preferences.mViewSphereLocation;
int Width = mView->mWidth;
int Height = mView->mHeight;
int ViewportSize = Preferences.mViewSphereSize;
int Left = (Location == lcViewSphereLocation::BOTTOM_LEFT || Location == lcViewSphereLocation::TOP_LEFT) ? 0 : Width - ViewportSize;
int Bottom = (Location == lcViewSphereLocation::BOTTOM_LEFT || Location == lcViewSphereLocation::BOTTOM_RIGHT) ? 0 : Height - ViewportSize;
int x = mView->mInputState.x - Left;
int y = mView->mInputState.y - Bottom;
std::bitset<6> IntersectionFlags;
if (x < 0 || x > Width || y < 0 || y > Height)
return IntersectionFlags;
lcVector3 StartEnd[2] = { lcVector3(x, y, 0), lcVector3(x, y, 1) };
const int Viewport[4] = { 0, 0, ViewportSize, ViewportSize };
lcUnprojectPoints(StartEnd, 2, GetViewMatrix(), GetProjectionMatrix(), Viewport);
float Distance;
if (lcSphereRayMinIntersectDistance(lcVector3(0.0f, 0.0f, 0.0f), BoxSize, StartEnd[0], StartEnd[1], &Distance))
{
Intersection = (StartEnd[0] + (StartEnd[1] - StartEnd[0]) * Distance) / BoxSize;
const float Side = 0.6f;
for (int AxisIdx = 0; AxisIdx < 3; AxisIdx++)
{
if (mIntersection[AxisIdx] > Side)
IntersectionFlags.set(2 * AxisIdx);
else if (mIntersection[AxisIdx] < -Side)
IntersectionFlags.set(2 * AxisIdx + 1);
}
}
return IntersectionFlags;
}

View file

@ -5,10 +5,10 @@
class View;
class lcViewCube
class lcViewSphere
{
public:
lcViewCube(View* View);
lcViewSphere(View* View);
void Draw();
bool OnMouseMove();
@ -16,6 +16,9 @@ public:
bool OnLeftButtonDown();
bool IsDragging() const;
static void CreateResources();
static void DestroyResources();
protected:
lcMatrix44 GetViewMatrix() const;
lcMatrix44 GetProjectionMatrix() const;
@ -27,4 +30,6 @@ protected:
int mMouseDownX;
int mMouseDownY;
bool mMouseDown;
static lcTexture* mTexture;
};

View file

@ -13,7 +13,7 @@ lcVertexBuffer View::mRotateMoveVertexBuffer;
lcIndexBuffer View::mRotateMoveIndexBuffer;
View::View(lcModel* Model)
: mViewCube(this)
: mViewSphere(this)
{
mModel = Model;
mActiveSubmodelInstance = nullptr;
@ -882,7 +882,7 @@ void View::OnDraw()
else if (Tool == LC_TOOL_ROTATE_VIEW && mTrackButton == LC_TRACKBUTTON_NONE)
DrawRotateViewOverlay();
mViewCube.Draw();
mViewSphere.Draw();
DrawViewport();
}
@ -2777,7 +2777,7 @@ void View::OnLeftButtonDown()
gMainWindow->SetActiveView(this);
if (mViewCube.OnLeftButtonDown())
if (mViewSphere.OnLeftButtonDown())
return;
lcTrackTool OverrideTool = GetOverrideTrackTool(Qt::LeftButton);
@ -2795,7 +2795,7 @@ void View::OnLeftButtonUp()
{
StopTracking(mTrackButton == LC_TRACKBUTTON_LEFT);
if (mViewCube.OnLeftButtonUp())
if (mViewSphere.OnLeftButtonUp())
return;
}
@ -2891,9 +2891,9 @@ void View::OnMouseMove()
if (mTrackButton == LC_TRACKBUTTON_NONE)
{
if (mViewCube.OnMouseMove())
if (mViewSphere.OnMouseMove())
{
lcTrackTool NewTrackTool = mViewCube.IsDragging() ? LC_TRACKTOOL_ORBIT_XY : LC_TRACKTOOL_NONE;
lcTrackTool NewTrackTool = mViewSphere.IsDragging() ? LC_TRACKTOOL_ORBIT_XY : LC_TRACKTOOL_NONE;
if (NewTrackTool != mTrackTool)
{

View file

@ -3,7 +3,7 @@
#include "lc_glwidget.h"
#include "camera.h"
#include "lc_scene.h"
#include "lc_viewcube.h"
#include "lc_viewsphere.h"
#include "lc_commands.h"
enum lcTrackButton
@ -197,7 +197,7 @@ protected:
bool mHighlight;
QImage mRenderImage;
std::pair<lcFramebuffer, lcFramebuffer> mRenderFramebuffer;
lcViewCube mViewCube;
lcViewSphere mViewSphere;
lcVertexBuffer mGridBuffer;
int mGridSettings[7];

View file

@ -161,7 +161,7 @@ SOURCES += common/view.cpp \
common/lc_stringcache.cpp \
common/lc_synth.cpp \
common/lc_texture.cpp \
common/lc_viewcube.cpp \
common/lc_viewsphere.cpp \
common/lc_zipfile.cpp \
common/image.cpp \
common/group.cpp \
@ -226,7 +226,7 @@ HEADERS += \
common/lc_stringcache.h \
common/lc_synth.h \
common/lc_texture.h \
common/lc_viewcube.h \
common/lc_viewsphere.h \
common/lc_zipfile.h \
common/image.h \
common/group.h \

View file

@ -10,6 +10,7 @@
#include "lc_context.h"
#include "view.h"
#include "texfont.h"
#include "lc_viewsphere.h"
#include "lc_stringcache.h"
#include "lc_texture.h"
#include "lc_mesh.h"
@ -102,6 +103,7 @@ lcQGLWidget::lcQGLWidget(QWidget *parent, lcGLWidget *owner, bool view)
lcInitializeGLExtensions(context());
lcContext::CreateResources();
View::CreateResources(widget->mContext);
lcViewSphere::CreateResources();
if (!gSupportsShaderObjects && lcGetPreferences().mShadingMode == LC_SHADING_DEFAULT_LIGHTS)
lcGetPreferences().mShadingMode = LC_SHADING_FLAT;
@ -138,6 +140,7 @@ lcQGLWidget::~lcQGLWidget()
lcGetPiecesLibrary()->ReleaseBuffers(widget->mContext);
View::DestroyResources(widget->mContext);
lcContext::DestroyResources();
lcViewSphere::DestroyResources();
delete gPlaceholderMesh;
gPlaceholderMesh = nullptr;

View file

@ -55,8 +55,8 @@ lcQPreferencesDialog::lcQPreferencesDialog(QWidget *parent, void *data) :
ui->gridLines->setChecked(options->Preferences.mDrawGridLines);
ui->gridLineSpacing->setText(QString::number(options->Preferences.mGridLineSpacing));
ui->axisIcon->setChecked(options->Preferences.mDrawAxes);
ui->ViewCubeLocationCombo->setCurrentIndex((int)options->Preferences.mViewCubeLocation);
ui->ViewCubeSizeEdit->setText(QString::number(options->Preferences.mViewCubeSize));
ui->ViewSphereLocationCombo->setCurrentIndex((int)options->Preferences.mViewSphereLocation);
ui->ViewSphereSizeEdit->setText(QString::number(options->Preferences.mViewSphereSize));
if (!gSupportsShaderObjects)
ui->ShadingMode->removeItem(LC_SHADING_DEFAULT_LIGHTS);
@ -134,8 +134,8 @@ void lcQPreferencesDialog::accept()
options->Preferences.mGridLineSpacing = gridLineSpacing;
options->Preferences.mDrawAxes = ui->axisIcon->isChecked();
options->Preferences.mViewCubeLocation = (lcViewCubeLocation)ui->ViewCubeLocationCombo->currentIndex();
options->Preferences.mViewCubeSize = ui->ViewCubeSizeEdit->text().toInt();
options->Preferences.mViewSphereLocation = (lcViewSphereLocation)ui->ViewSphereLocationCombo->currentIndex();
options->Preferences.mViewSphereSize = ui->ViewSphereSizeEdit->text().toInt();
options->Preferences.mShadingMode = (lcShadingMode)ui->ShadingMode->currentIndex();
QDialog::accept();

View file

@ -325,9 +325,9 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="ViewCubeGroup">
<widget class="QGroupBox" name="ViewSphereGroup">
<property name="title">
<string>View Cube</string>
<string>View Sphere</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
@ -338,7 +338,7 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="ViewCubeLocationCombo">
<widget class="QComboBox" name="ViewSphereLocationCombo">
<item>
<property name="text">
<string>Disabled</string>
@ -374,7 +374,7 @@
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="ViewCubeSizeEdit"/>
<widget class="QLineEdit" name="ViewSphereSizeEdit"/>
</item>
</layout>
</widget>
@ -928,8 +928,8 @@
<tabstop>gridLines</tabstop>
<tabstop>gridLineSpacing</tabstop>
<tabstop>gridLineColor</tabstop>
<tabstop>ViewCubeLocationCombo</tabstop>
<tabstop>ViewCubeSizeEdit</tabstop>
<tabstop>ViewSphereLocationCombo</tabstop>
<tabstop>ViewSphereSizeEdit</tabstop>
<tabstop>categoriesTree</tabstop>
<tabstop>partsTree</tabstop>
<tabstop>importCategories</tabstop>