1
0
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:
XProger
2017-06-19 06:19:04 +03:00
parent 0b8ca6f21e
commit 0d8cb3c283
4 changed files with 51 additions and 30 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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;
} }
} }