1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-04-21 19:41:53 +02:00

#16 VAO, profiling markers and configuration, smart shader binding

This commit is contained in:
XProger 2016-11-03 23:39:27 +03:00
parent eb37622b15
commit 9d13776c5f
8 changed files with 261 additions and 100 deletions

View File

@ -72,11 +72,42 @@
PFNGLDELETEBUFFERSARBPROC glDeleteBuffers;
PFNGLBINDBUFFERARBPROC glBindBuffer;
PFNGLBUFFERDATAARBPROC glBufferData;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
// Profiling
#ifdef PROFILE
PFNGLOBJECTLABELPROC glObjectLabel;
PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup;
PFNGLPOPDEBUGGROUPPROC glPopDebugGroup;
#endif
#endif
struct Shader;
struct Texture;
#ifdef PROFILE
struct Marker {
Marker(const char *title) {
if (glPushDebugGroup) glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, title);
}
~Marker() {
if (glPopDebugGroup) glPopDebugGroup();
}
static void setLabel(GLenum id, GLuint name, const char *label) {
if (glObjectLabel) glObjectLabel(id, name, -1, label);
}
};
#define PROFILE_MARKER(title) Marker marker(title)
#define PROFILE_LABEL(id, name, label) Marker::setLabel(GL_##id, name, label)
#else
#define PROFILE_MARKER(title)
#define PROFILE_LABEL(id, name, label)
#endif
namespace Core {
int width, height;
float deltaTime;
@ -96,13 +127,17 @@ namespace Core {
int dips;
int tris;
} stats;
struct {
bool VAO;
} support;
}
#include "texture.h"
#include "shader.h"
#include "mesh.h"
enum CullMode { cfNone, cfBack, cfFront };
enum CullMode { cfNone, cfBack, cfFront };
enum BlendMode { bmNone, bmAlpha, bmAdd, bmMultiply, bmScreen };
namespace Core {
@ -138,7 +173,17 @@ namespace Core {
GetProcOGL(glDeleteBuffers);
GetProcOGL(glBindBuffer);
GetProcOGL(glBufferData);
GetProcOGL(glGenVertexArrays);
GetProcOGL(glDeleteVertexArrays);
GetProcOGL(glBindVertexArray);
#ifdef PROFILE
GetProcOGL(glObjectLabel);
GetProcOGL(glPushDebugGroup);
GetProcOGL(glPopDebugGroup);
#endif
#endif
support.VAO = (void*)glBindVertexArray != NULL;
Sound::init();
}

View File

@ -163,6 +163,7 @@ struct Level {
atlas = new Texture(1024, 1024, 0, data);
delete[] data;
PROFILE_LABEL(TEXTURE, atlas->ID, "atlas");
}
void initShaders() {
@ -224,6 +225,7 @@ struct Level {
void renderRoom(int roomIndex, int from = -1) {
ASSERT(roomIndex >= 0 && roomIndex < level.roomsCount);
PROFILE_MARKER("ROOM");
TR::Room &room = level.rooms[roomIndex];
vec3 offset = vec3(room.info.x, 0.0f, room.info.z);
@ -234,50 +236,60 @@ struct Level {
sh->setParam(uColor, Core::color);
// room static meshes
for (int i = 0; i < room.meshesCount; i++) {
TR::Room::Mesh &rMesh = room.meshes[i];
if (rMesh.flags.rendered) continue; // skip if already rendered
{
PROFILE_MARKER("R_MESH");
TR::StaticMesh *sMesh = level.getMeshByID(rMesh.meshID);
ASSERT(sMesh != NULL);
for (int i = 0; i < room.meshesCount; i++) {
TR::Room::Mesh &rMesh = room.meshes[i];
if (rMesh.flags.rendered) continue; // skip if already rendered
// check visibility
Box box;
vec3 offset = vec3(rMesh.x, rMesh.y, rMesh.z);
sMesh->getBox(false, rMesh.rotation, box);
if (!camera->frustum->isVisible(offset + box.min, offset + box.max))
continue;
rMesh.flags.rendered = true;
TR::StaticMesh *sMesh = level.getMeshByID(rMesh.meshID);
ASSERT(sMesh != NULL);
// set light parameters
getLight(offset, roomIndex);
// check visibility
Box box;
vec3 offset = vec3(rMesh.x, rMesh.y, rMesh.z);
sMesh->getBox(false, rMesh.rotation, box);
if (!camera->frustum->isVisible(offset + box.min, offset + box.max))
continue;
rMesh.flags.rendered = true;
// render static mesh
mat4 mTemp = Core::mModel;
Core::mModel.translate(offset);
Core::mModel.rotateY(rMesh.rotation);
renderMesh(sMesh->mesh);
Core::mModel = mTemp;
// set light parameters
getLight(offset, roomIndex);
// render static mesh
mat4 mTemp = Core::mModel;
Core::mModel.translate(offset);
Core::mModel.rotateY(rMesh.rotation);
renderMesh(sMesh->mesh);
Core::mModel = mTemp;
}
}
// room geometry & sprites
if (!room.flags.rendered) { // skip if already rendered
room.flags.rendered = true;
Core::lightColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
Core::ambient = vec3(1.0f);
sh->setParam(uLightColor, Core::lightColor);
sh->setParam(uAmbient, Core::ambient);
mat4 mTemp = Core::mModel;
Core::mModel.translate(offset);
{
PROFILE_MARKER("R_GEOM");
// render room geometry
sh->setParam(uModel, Core::mModel);
mesh->renderRoomGeometry(roomIndex);
room.flags.rendered = true;
Core::lightColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
Core::ambient = vec3(1.0f);
sh->setParam(uLightColor, Core::lightColor);
sh->setParam(uAmbient, Core::ambient);
Core::mModel.translate(offset);
// render room geometry
sh->setParam(uModel, Core::mModel);
mesh->renderRoomGeometry(roomIndex);
}
// render room sprites
if (mesh->hasRoomSprites(roomIndex)) {
PROFILE_MARKER("R_SPR");
sh = shaders[shSprite];
sh->bind();
sh->setParam(uModel, Core::mModel);
@ -539,10 +551,13 @@ struct Level {
getLight(vec3(entity.x, entity.y, entity.z), entity.room);
// render entity models
if (entity.modelIndex > 0)
if (entity.modelIndex > 0) {
PROFILE_MARKER("MDL");
renderModel(level.models[entity.modelIndex - 1], entity);
}
// if entity is billboard
if (entity.modelIndex < 0) {
PROFILE_MARKER("SPR");
Core::color = vec4(c, c, c, 1.0f);
renderSequence(entity);
}
@ -563,23 +578,25 @@ struct Level {
camera->update();
}
void render() {
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
void setup() {
PROFILE_MARKER("SETUP");
camera->setup();;
atlas->bind(0);
mesh->bind();
// set frame constants for all shaders
if (!Core::support.VAO)
mesh->bind();
// set frame constants for all shaders
Core::active.shader = NULL;
for (int i = 0; i < shMAX; i++) {
shaders[i]->bind();
shaders[i]->setParam(uViewProj, Core::mViewProj);
shaders[i]->setParam(uViewInv, Core::mViewInv);
shaders[i]->setParam(uViewPos, Core::viewPos);
shaders[i]->setParam(uParam, vec4(time, 0, 0, 0));
shaders[i]->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
shaders[i]->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
shaders[i]->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
shaders[i]->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
}
glEnable(GL_DEPTH_TEST);
@ -587,63 +604,45 @@ struct Level {
Core::mModel.identity();
// clear visible flags for rooms & static meshes
// clear visible flags for rooms & static meshes
for (int i = 0; i < level.roomsCount; i++) {
TR::Room &room = level.rooms[i];
room.flags.rendered = false; // clear visible flag for room geometry & sprites
for (int j = 0; j < room.meshesCount; j++)
room.meshes[j].flags.rendered = false; // clear visible flag for room static meshes
}
}
}
// TODO: collision detection for camera
void renderRooms() {
PROFILE_MARKER("ROOMS");
renderRoom(camera->getRoomIndex());
}
void renderEntities() {
PROFILE_MARKER("ENTITIES");
shaders[shStatic]->bind();
for (int i = 0; i < level.entitiesCount; i++)
renderEntity(level.entities[i]);
}
/*
static int modelIndex = 0;
static bool lastStateK = false;
void renderScene() {
PROFILE_MARKER("SCENE");
setup();
renderRooms();
renderEntities();
}
static int lastEntity = -1;
if (Input::down[ikM]) {
if (!lastStateK) {
lastStateK = true;
// modelIndex = (modelIndex + 1) % level.modelsCount;
modelIndex = (modelIndex + 1) % level.spriteSequencesCount;
LOG("model: %d %d\n", modelIndex, level.spriteSequences[modelIndex].id);
if (lastEntity > -1) {
delete level.entities[lastEntity].controller;
level.entityRemove(lastEntity);
}
lastEntity = level.entityAdd(level.models[modelIndex].id, lara->getRoomIndex(), lara->pos.x + 1024, lara->pos.y - 1024, lara->pos.z, lara->getEntity().rotation, -1);
level.entities[lastEntity].controller = new Controller(&level, lastEntity);
}
} else
lastStateK = false;
Core::mModel.translate(lara->pos + vec3(512, -512, 0));
if (lastEntity > -1)
renderEntity(level.entities[lastEntity]);
// renderModel(level.models[modelIndex], level.entities[4]);
*/
/*
TR::Entity seq;
seq.modelIndex = -(modelIndex + 1);
seq.controller = NULL;
Core::color = vec4(1.0f);
renderSequence(seq);
*/
void render() {
renderScene();
#ifdef _DEBUG
Debug::begin();
// Debug::Level::rooms(level, lara->pos, lara->getEntity().room);
// Debug::Level::lights(level);
// Debug::Level::portals(level);
// Debug::Level::meshes(level);
// Debug::Level::entities(level);
// Debug::Level::rooms(level, lara->pos, lara->getEntity().room);
// Debug::Level::lights(level);
// Debug::Level::portals(level);
// Debug::Level::meshes(level);
// Debug::Level::entities(level);
Debug::Level::info(level, lara->getEntity(), (int)lara->state, lara->animIndex, int(lara->animTime * 30.0f));
Debug::end();
#endif

View File

@ -17,24 +17,64 @@ struct MeshRange {
int iStart;
int iCount;
int vStart;
int aIndex;
MeshRange() : aIndex(-1) {}
void setup() const {
Vertex *v = (Vertex*)(vStart * sizeof(Vertex));
glVertexAttribPointer(aCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->coord);
glVertexAttribPointer(aTexCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->texCoord);
glVertexAttribPointer(aNormal, 4, GL_SHORT, false, sizeof(Vertex), &v->normal);
glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), &v->color);
}
void bind(GLuint *VAO) const {
if (aIndex > -1)
glBindVertexArray(VAO[aIndex]);
else
setup();
}
};
struct Mesh {
GLuint ID[2];
GLuint *VAO;
int iCount;
int vCount;
int aCount;
int aIndex;
Mesh(Index *indices, int iCount, Vertex *vertices, int vCount) : iCount(iCount), vCount(vCount) {
Mesh(Index *indices, int iCount, Vertex *vertices, int vCount, int aCount) : VAO(NULL), iCount(iCount), vCount(vCount), aCount(aCount), aIndex(0) {
glGenBuffers(2, ID);
bind();
glBufferData(GL_ELEMENT_ARRAY_BUFFER, iCount * sizeof(Index), indices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, vCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);
if (Core::support.VAO && aCount) {
VAO = new GLuint[aCount];
glGenVertexArrays(aCount, VAO);
}
}
virtual ~Mesh() {
if (VAO) {
glDeleteVertexArrays(aCount, VAO);
delete[] VAO;
}
glDeleteBuffers(2, ID);
}
void initRange(MeshRange &range) {
if (Core::support.VAO) {
range.aIndex = aIndex++;
range.bind(VAO);
bind();
range.setup();
} else
range.aIndex = -1;
}
void bind() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ID[0]);
glBindBuffer(GL_ARRAY_BUFFER, ID[1]);
@ -46,11 +86,7 @@ struct Mesh {
}
void render(const MeshRange &range) {
Vertex *v = (Vertex*)(range.vStart * sizeof(Vertex));
glVertexAttribPointer(aCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->coord);
glVertexAttribPointer(aTexCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->texCoord);
glVertexAttribPointer(aNormal, 4, GL_SHORT, false, sizeof(Vertex), &v->normal);
glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), &v->color);
range.bind(VAO);
glDrawElements(GL_TRIANGLES, range.iCount, GL_UNSIGNED_SHORT, (GLvoid*)(range.iStart * sizeof(Index)));
Core::stats.dips++;
@ -119,7 +155,7 @@ struct MeshBuilder {
// allocate room geometry ranges
roomRanges = new RoomRange[level.roomsCount];
int iCount = 0, vCount = 0;
int iCount = 0, vCount = 0, aCount = 0;
// get size of mesh for rooms (geometry & sprites)
for (int i = 0; i < level.roomsCount; i++) {
@ -131,13 +167,16 @@ struct MeshBuilder {
iCount += d.rCount * 6 + d.tCount * 3;
vCount += d.rCount * 4 + d.tCount * 3;
r.geometry.iCount = iCount - r.geometry.iStart;
r.sprites.vStart = vCount;
r.sprites.iStart = iCount;
iCount += d.sCount * 6;
vCount += d.sCount * 4;
r.sprites.iCount = iCount - r.sprites.iStart;
if (r.sprites.iCount)
aCount++;
}
aCount += level.roomsCount;
// get objects mesh info
#define OFFSET(bytes) (ptr = (TR::Mesh*)((char*)ptr + (bytes) - sizeof(char*)))
@ -170,6 +209,7 @@ struct MeshBuilder {
OFFSET(ptr->ctCount * sizeof(TR::Triangle) + sizeof(TR::Mesh));
ptr = (TR::Mesh*)(((intptr_t)ptr + 3) & -4);
}
aCount += mCount;
meshInfo = new MeshInfo[mCount];
// get size of mesh for sprite sequences
@ -182,11 +222,13 @@ struct MeshBuilder {
iCount += level.spriteSequences[i].sCount * 6;
vCount += level.spriteSequences[i].sCount * 4;
}
aCount += level.spriteSequencesCount;
// get size of simple shadow spot mesh (8 triangles, 8 vertices)
shadowBlob.vStart = vCount;
shadowBlob.iStart = iCount;
shadowBlob.iCount = 8 * 3;
aCount++;
iCount += shadowBlob.iCount;
vCount += 8;
@ -220,7 +262,7 @@ struct MeshBuilder {
for (int j = 0; j < d.tCount; j++) {
TR::Triangle &f = d.triangles[j];
TR::ObjectTexture &t = level.objectTextures[f.texture];
TR::ObjectTexture &t = level.objectTextures[f.texture];
addTriangle(indices, iCount, vCount, vStart, vertices, &t);
@ -239,7 +281,7 @@ struct MeshBuilder {
TR::Room::Info &info = level.rooms[i].info;
vStart = vCount;
for (int j = 0; j < d.sCount; j++) {
TR::Room::Data::Sprite &f = d.sprites[j];
TR::Room::Data::Sprite &f = d.sprites[j];
TR::Room::Data::Vertex &v = d.vertices[f.vertex];
TR::SpriteTexture &sprite = level.spriteTextures[f.texture];
@ -415,9 +457,25 @@ struct MeshBuilder {
iCount += shadowBlob.iCount;
vCount += 8;
mesh = new Mesh(indices, iCount, vertices, vCount);
mesh = new Mesh(indices, iCount, vertices, vCount, aCount);
delete[] indices;
delete[] vertices;
PROFILE_LABEL(BUFFER, mesh->ID[0], "Geometry indices");
PROFILE_LABEL(BUFFER, mesh->ID[1], "Geometry vertices");
// initialize Vertex Arrays
for (int i = 0; i < level.roomsCount; i++) {
RoomRange &r = roomRanges[i];
mesh->initRange(r.geometry);
if (r.sprites.iCount)
mesh->initRange(r.sprites);
}
for (int i = 0; i < level.spriteSequencesCount; i++)
mesh->initRange(spriteSequences[i]);
for (int i = 0; i < mCount; i++)
mesh->initRange(meshInfo[i]);
mesh->initRange(shadowBlob);
}
~MeshBuilder() {
@ -461,7 +519,7 @@ struct MeshBuilder {
ptr = &level.animTexturesData[1];
for (int i = 1; i < animTexRangesCount; i++) {
int start = animTexOffsetsCount;
TR::AnimTexture *animTex = (TR::AnimTexture*)ptr;
TR::AnimTexture *animTex = (TR::AnimTexture*)ptr;
vec2 first = getTexCoord(level.objectTextures[animTex->textures[0]]);
animTexOffsets[animTexOffsetsCount++] = vec2(0.0f); // first - first for first frame %)
@ -480,7 +538,7 @@ struct MeshBuilder {
uint16 *ptr = &level->animTexturesData[1];
for (int i = 1; i < animTexRangesCount; i++) {
TR::AnimTexture *animTex = (TR::AnimTexture*)ptr;
TR::AnimTexture *animTex = (TR::AnimTexture*)ptr;
for (int j = 0; j <= animTex->count; j++)
if (tex == &level->objectTextures[animTex->textures[j]]) {

View File

@ -8,11 +8,14 @@ EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Profile|Win32 = Profile|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6935E070-59B8-418A-9241-70BACB4217B5}.Debug|Win32.ActiveCfg = Debug|Win32
{6935E070-59B8-418A-9241-70BACB4217B5}.Debug|Win32.Build.0 = Debug|Win32
{6935E070-59B8-418A-9241-70BACB4217B5}.Profile|Win32.ActiveCfg = Profile|Win32
{6935E070-59B8-418A-9241-70BACB4217B5}.Profile|Win32.Build.0 = Profile|Win32
{6935E070-59B8-418A-9241-70BACB4217B5}.Release|Win32.ActiveCfg = Release|Win32
{6935E070-59B8-418A-9241-70BACB4217B5}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection

View File

@ -5,6 +5,10 @@
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Profile|Win32">
<Configuration>Profile</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
@ -29,6 +33,13 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@ -38,6 +49,9 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
@ -50,6 +64,12 @@
<GenerateManifest>false</GenerateManifest>
<IncludePath>..\..\;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>..\..\..\bin\</OutDir>
<GenerateManifest>false</GenerateManifest>
<IncludePath>..\..\;$(VC_IncludePath);$(WindowsSdk_71A_IncludePath);</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
@ -96,6 +116,35 @@
<RandomizedBaseAddress>false</RandomizedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>PROFILE;MINIMAL;STB_VORBIS_NO_STDIO;NOMINMAX;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FloatingPointModel>Strict</FloatingPointModel>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalOptions>/d2noftol3 %(AdditionalOptions)</AdditionalOptions>
<WholeProgramOptimization>true</WholeProgramOptimization>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>wcrt.lib;opengl32.lib;winmm.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\libs\minimp3\minimp3.cpp" />
<ClCompile Include="..\..\libs\stb_vorbis\stb_vorbis.c" />

View File

@ -271,14 +271,16 @@ void freeGL(HGLRC hRC) {
wglDeleteContext(hRC);
}
#ifndef _DEBUG
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
#else
#ifdef _DEBUG
int main() {
_CrtMemState _ms;
_CrtMemCheckpoint(&_ms);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
#elif PROFILE
int main() {
#else
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
#endif
RECT r = { 0, 0, 1280, 720 };
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW, false);

View File

@ -64,8 +64,10 @@ struct Shader {
}
void bind() {
glUseProgram(ID);
Core::active.shader = this;
if (Core::active.shader != this) {
Core::active.shader = this;
glUseProgram(ID);
}
}
void setParam(UniformType uType, const vec2 &value, int count = 1) {

View File

@ -19,8 +19,11 @@
#else
#define ASSERT(expr)
#define LOG(...)
// #define LOG(...) printf(__VA_ARGS__)
#ifdef PROFILE
#define LOG(...) printf(__VA_ARGS__)
#else
#define LOG(...)
#endif
#endif