mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-29 15:59:59 +02:00
#11 fix OGL ES inventory text rendering (add dynamic mesh)
This commit is contained in:
@@ -203,6 +203,7 @@ namespace Core {
|
|||||||
PFNGLDELETEBUFFERSARBPROC glDeleteBuffers;
|
PFNGLDELETEBUFFERSARBPROC glDeleteBuffers;
|
||||||
PFNGLBINDBUFFERARBPROC glBindBuffer;
|
PFNGLBINDBUFFERARBPROC glBindBuffer;
|
||||||
PFNGLBUFFERDATAARBPROC glBufferData;
|
PFNGLBUFFERDATAARBPROC glBufferData;
|
||||||
|
PFNGLBUFFERSUBDATAARBPROC glBufferSubData;
|
||||||
// Stencil
|
// Stencil
|
||||||
PFNGLACTIVESTENCILFACEEXTPROC glActiveStencilFaceEXT;
|
PFNGLACTIVESTENCILFACEEXTPROC glActiveStencilFaceEXT;
|
||||||
PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate;
|
PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate;
|
||||||
@@ -437,7 +438,8 @@ namespace Core {
|
|||||||
GetProcOGL(glDeleteBuffers);
|
GetProcOGL(glDeleteBuffers);
|
||||||
GetProcOGL(glBindBuffer);
|
GetProcOGL(glBindBuffer);
|
||||||
GetProcOGL(glBufferData);
|
GetProcOGL(glBufferData);
|
||||||
|
GetProcOGL(glBufferSubData);
|
||||||
|
|
||||||
GetProcOGL(glActiveStencilFaceEXT);
|
GetProcOGL(glActiveStencilFaceEXT);
|
||||||
GetProcOGL(glStencilFuncSeparate);
|
GetProcOGL(glStencilFuncSeparate);
|
||||||
GetProcOGL(glStencilOpSeparate);
|
GetProcOGL(glStencilOpSeparate);
|
||||||
|
@@ -140,11 +140,11 @@ struct Inventory {
|
|||||||
add(TR::Entity::INV_CONTROLS);
|
add(TR::Entity::INV_CONTROLS);
|
||||||
add(TR::Entity::INV_COMPASS);
|
add(TR::Entity::INV_COMPASS);
|
||||||
|
|
||||||
if (level->extra.inv.map)
|
if (level->extra.inv.map != -1)
|
||||||
add(TR::Entity::INV_MAP);
|
add(TR::Entity::INV_MAP);
|
||||||
if (level->extra.inv.gamma)
|
if (level->extra.inv.gamma != -1)
|
||||||
add(TR::Entity::INV_GAMMA);
|
add(TR::Entity::INV_GAMMA);
|
||||||
|
|
||||||
add(TR::Entity::INV_PISTOLS, 999);
|
add(TR::Entity::INV_PISTOLS, 999);
|
||||||
add(TR::Entity::INV_SHOTGUN, 999);
|
add(TR::Entity::INV_SHOTGUN, 999);
|
||||||
add(TR::Entity::INV_MAGNUMS, 999);
|
add(TR::Entity::INV_MAGNUMS, 999);
|
||||||
|
67
src/mesh.h
67
src/mesh.h
@@ -21,13 +21,13 @@ struct MeshRange {
|
|||||||
|
|
||||||
MeshRange() : aIndex(-1) {}
|
MeshRange() : aIndex(-1) {}
|
||||||
|
|
||||||
void setup(Vertex *offset) const {
|
void setup() const {
|
||||||
glEnableVertexAttribArray(aCoord);
|
glEnableVertexAttribArray(aCoord);
|
||||||
glEnableVertexAttribArray(aTexCoord);
|
glEnableVertexAttribArray(aTexCoord);
|
||||||
glEnableVertexAttribArray(aNormal);
|
glEnableVertexAttribArray(aNormal);
|
||||||
glEnableVertexAttribArray(aColor);
|
glEnableVertexAttribArray(aColor);
|
||||||
|
|
||||||
Vertex *v = (Vertex*)(offset + vStart);
|
Vertex *v = (Vertex*)NULL + vStart;
|
||||||
glVertexAttribPointer(aCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->coord);
|
glVertexAttribPointer(aCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->coord);
|
||||||
glVertexAttribPointer(aTexCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->texCoord);
|
glVertexAttribPointer(aTexCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->texCoord);
|
||||||
glVertexAttribPointer(aNormal, 4, GL_SHORT, true, sizeof(Vertex), &v->normal);
|
glVertexAttribPointer(aNormal, 4, GL_SHORT, true, sizeof(Vertex), &v->normal);
|
||||||
@@ -44,6 +44,8 @@ struct MeshRange {
|
|||||||
#define PLANE_DETAIL 48
|
#define PLANE_DETAIL 48
|
||||||
#define CIRCLE_SEGS 16
|
#define CIRCLE_SEGS 16
|
||||||
|
|
||||||
|
#define DYN_MESH_QUADS 1024
|
||||||
|
|
||||||
struct Mesh {
|
struct Mesh {
|
||||||
GLuint ID[2];
|
GLuint ID[2];
|
||||||
GLuint *VAO;
|
GLuint *VAO;
|
||||||
@@ -53,6 +55,9 @@ struct Mesh {
|
|||||||
int aIndex;
|
int aIndex;
|
||||||
|
|
||||||
Mesh(Index *indices, int iCount, Vertex *vertices, int vCount, int aCount) : VAO(NULL), iCount(iCount), vCount(vCount), aCount(aCount), aIndex(0) {
|
Mesh(Index *indices, int iCount, Vertex *vertices, int vCount, int aCount) : VAO(NULL), iCount(iCount), vCount(vCount), aCount(aCount), aIndex(0) {
|
||||||
|
if (Core::support.VAO)
|
||||||
|
glBindVertexArray(Core::active.VAO = 0);
|
||||||
|
|
||||||
glGenBuffers(2, ID);
|
glGenBuffers(2, ID);
|
||||||
bind(true);
|
bind(true);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, iCount * sizeof(Index), indices, GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, iCount * sizeof(Index), indices, GL_STATIC_DRAW);
|
||||||
@@ -64,6 +69,20 @@ struct Mesh {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update(Index *indices, int iCount, Vertex *vertices, int vCount) {
|
||||||
|
if (Core::support.VAO)
|
||||||
|
glBindVertexArray(Core::active.VAO = 0);
|
||||||
|
|
||||||
|
if (indices && iCount) {
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Core::active.iBuffer = ID[0]);
|
||||||
|
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, iCount * sizeof(Index), indices);
|
||||||
|
}
|
||||||
|
if (vertices && vCount) {
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, Core::active.vBuffer = ID[1]);
|
||||||
|
glBufferSubData(GL_ARRAY_BUFFER, 0, vCount * sizeof(Vertex), vertices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~Mesh() {
|
virtual ~Mesh() {
|
||||||
if (VAO) {
|
if (VAO) {
|
||||||
glDeleteVertexArrays(aCount, VAO);
|
glDeleteVertexArrays(aCount, VAO);
|
||||||
@@ -77,7 +96,7 @@ struct Mesh {
|
|||||||
range.aIndex = aIndex++;
|
range.aIndex = aIndex++;
|
||||||
range.bind(VAO);
|
range.bind(VAO);
|
||||||
bind(true);
|
bind(true);
|
||||||
range.setup(NULL);
|
range.setup();
|
||||||
} else
|
} else
|
||||||
range.aIndex = -1;
|
range.aIndex = -1;
|
||||||
}
|
}
|
||||||
@@ -89,37 +108,29 @@ struct Mesh {
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, Core::active.vBuffer = ID[1]);
|
glBindBuffer(GL_ARRAY_BUFFER, Core::active.vBuffer = ID[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unbind() {
|
void DIP(const MeshRange &range) {
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Core::active.iBuffer = 0);
|
glDrawElements(GL_TRIANGLES, range.iCount, GL_UNSIGNED_SHORT, (Index*)NULL + range.iStart);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, Core::active.vBuffer = 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DIP(const MeshRange &range, Index *iOffset = 0) {
|
|
||||||
glDrawElements(GL_TRIANGLES, range.iCount, GL_UNSIGNED_SHORT, (GLvoid*)(iOffset + range.iStart) );
|
|
||||||
Core::stats.dips++;
|
Core::stats.dips++;
|
||||||
Core::stats.tris += range.iCount / 3;
|
Core::stats.tris += range.iCount / 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(const MeshRange &range, Index *iOffset = NULL, Vertex *vOffset = NULL) {
|
void render(const MeshRange &range) {
|
||||||
range.bind(VAO);
|
range.bind(VAO);
|
||||||
|
|
||||||
if (vOffset) {
|
if (range.aIndex == -1) {
|
||||||
unbind();
|
|
||||||
range.setup(vOffset);
|
|
||||||
} else if (range.aIndex == -1) {
|
|
||||||
bind();
|
bind();
|
||||||
range.setup(NULL);
|
range.setup();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (Core::active.stencilTwoSide && Core::support.stencil == 0) {
|
if (Core::active.stencilTwoSide && Core::support.stencil == 0) {
|
||||||
Core::setCulling(cfBack);
|
Core::setCulling(cfBack);
|
||||||
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
|
||||||
DIP(range, iOffset);
|
DIP(range);
|
||||||
Core::setCulling(cfFront);
|
Core::setCulling(cfFront);
|
||||||
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
DIP(range, iOffset);
|
DIP(range);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -156,6 +167,9 @@ uint8 intensity(int lighting) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct MeshBuilder {
|
struct MeshBuilder {
|
||||||
|
MeshRange dynRange;
|
||||||
|
Mesh *dynMesh;
|
||||||
|
|
||||||
Mesh *mesh;
|
Mesh *mesh;
|
||||||
// level
|
// level
|
||||||
struct RoomRange {
|
struct RoomRange {
|
||||||
@@ -184,6 +198,11 @@ struct MeshBuilder {
|
|||||||
TR::ObjectTexture whiteTile;
|
TR::ObjectTexture whiteTile;
|
||||||
|
|
||||||
MeshBuilder(TR::Level &level) : level(&level) {
|
MeshBuilder(TR::Level &level) : level(&level) {
|
||||||
|
dynMesh = new Mesh(NULL, DYN_MESH_QUADS * 6, NULL, DYN_MESH_QUADS * 4, 1);
|
||||||
|
dynRange.vStart = 0;
|
||||||
|
dynRange.iStart = 0;
|
||||||
|
dynMesh->initRange(dynRange);
|
||||||
|
|
||||||
initAnimTextures(level);
|
initAnimTextures(level);
|
||||||
|
|
||||||
// create dummy white object textures for non-textured (colored) geometry
|
// create dummy white object textures for non-textured (colored) geometry
|
||||||
@@ -589,6 +608,7 @@ struct MeshBuilder {
|
|||||||
delete[] models;
|
delete[] models;
|
||||||
delete[] sequences;
|
delete[] sequences;
|
||||||
delete mesh;
|
delete mesh;
|
||||||
|
delete dynMesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline short4 rotate(const short4 &v, int dir) {
|
inline short4 rotate(const short4 &v, int dir) {
|
||||||
@@ -962,13 +982,12 @@ struct MeshBuilder {
|
|||||||
mesh->bind();
|
mesh->bind();
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderBuffer(Index *indices, Vertex *vertices, int iCount) {
|
void renderBuffer(Index *indices, int iCount, Vertex *vertices, int vCount) {
|
||||||
MeshRange range;
|
dynRange.iStart = 0;
|
||||||
range.iStart = 0;
|
dynRange.iCount = iCount;
|
||||||
range.vStart = 0;
|
|
||||||
range.iCount = iCount;
|
|
||||||
|
|
||||||
mesh->render(range, indices, vertices);
|
dynMesh->update(indices, iCount, vertices, vCount);
|
||||||
|
dynMesh->render(dynRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderRoomGeometry(int roomIndex, bool transparent) {
|
void renderRoomGeometry(int roomIndex, bool transparent) {
|
||||||
|
4
src/ui.h
4
src/ui.h
@@ -34,7 +34,7 @@ namespace UI {
|
|||||||
return width - 1;
|
return width - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_CHARS 1024
|
#define MAX_CHARS DYN_MESH_QUADS
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
Vertex vertices[MAX_CHARS * 4];
|
Vertex vertices[MAX_CHARS * 4];
|
||||||
@@ -49,7 +49,7 @@ namespace UI {
|
|||||||
|
|
||||||
void textEnd(IGame *game) {
|
void textEnd(IGame *game) {
|
||||||
if (buffer.iCount > 0) {
|
if (buffer.iCount > 0) {
|
||||||
game->getMesh()->renderBuffer(buffer.indices, buffer.vertices, buffer.iCount);
|
game->getMesh()->renderBuffer(buffer.indices, buffer.iCount, buffer.vertices, buffer.vCount);
|
||||||
buffer.iCount = buffer.vCount = 0;
|
buffer.iCount = buffer.vCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user