1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-30 00:10:09 +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;
PFNGLBINDBUFFERARBPROC glBindBuffer;
PFNGLBUFFERDATAARBPROC glBufferData;
PFNGLBUFFERSUBDATAARBPROC glBufferSubData;
// Stencil
PFNGLACTIVESTENCILFACEEXTPROC glActiveStencilFaceEXT;
PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate;
@@ -437,6 +438,7 @@ namespace Core {
GetProcOGL(glDeleteBuffers);
GetProcOGL(glBindBuffer);
GetProcOGL(glBufferData);
GetProcOGL(glBufferSubData);
GetProcOGL(glActiveStencilFaceEXT);
GetProcOGL(glStencilFuncSeparate);

View File

@@ -140,9 +140,9 @@ struct Inventory {
add(TR::Entity::INV_CONTROLS);
add(TR::Entity::INV_COMPASS);
if (level->extra.inv.map)
if (level->extra.inv.map != -1)
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_PISTOLS, 999);

View File

@@ -21,13 +21,13 @@ struct MeshRange {
MeshRange() : aIndex(-1) {}
void setup(Vertex *offset) const {
void setup() const {
glEnableVertexAttribArray(aCoord);
glEnableVertexAttribArray(aTexCoord);
glEnableVertexAttribArray(aNormal);
glEnableVertexAttribArray(aColor);
Vertex *v = (Vertex*)(offset + vStart);
Vertex *v = (Vertex*)NULL + vStart;
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, true, sizeof(Vertex), &v->normal);
@@ -44,6 +44,8 @@ struct MeshRange {
#define PLANE_DETAIL 48
#define CIRCLE_SEGS 16
#define DYN_MESH_QUADS 1024
struct Mesh {
GLuint ID[2];
GLuint *VAO;
@@ -53,6 +55,9 @@ struct Mesh {
int aIndex;
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);
bind(true);
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() {
if (VAO) {
glDeleteVertexArrays(aCount, VAO);
@@ -77,7 +96,7 @@ struct Mesh {
range.aIndex = aIndex++;
range.bind(VAO);
bind(true);
range.setup(NULL);
range.setup();
} else
range.aIndex = -1;
}
@@ -89,37 +108,29 @@ struct Mesh {
glBindBuffer(GL_ARRAY_BUFFER, Core::active.vBuffer = ID[1]);
}
void unbind() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Core::active.iBuffer = 0);
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) );
void DIP(const MeshRange &range) {
glDrawElements(GL_TRIANGLES, range.iCount, GL_UNSIGNED_SHORT, (Index*)NULL + range.iStart);
Core::stats.dips++;
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);
if (vOffset) {
unbind();
range.setup(vOffset);
} else if (range.aIndex == -1) {
if (range.aIndex == -1) {
bind();
range.setup(NULL);
range.setup();
};
if (Core::active.stencilTwoSide && Core::support.stencil == 0) {
Core::setCulling(cfBack);
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
DIP(range, iOffset);
DIP(range);
Core::setCulling(cfFront);
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
}
DIP(range, iOffset);
DIP(range);
}
};
@@ -156,6 +167,9 @@ uint8 intensity(int lighting) {
}
struct MeshBuilder {
MeshRange dynRange;
Mesh *dynMesh;
Mesh *mesh;
// level
struct RoomRange {
@@ -184,6 +198,11 @@ struct MeshBuilder {
TR::ObjectTexture whiteTile;
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);
// create dummy white object textures for non-textured (colored) geometry
@@ -589,6 +608,7 @@ struct MeshBuilder {
delete[] models;
delete[] sequences;
delete mesh;
delete dynMesh;
}
inline short4 rotate(const short4 &v, int dir) {
@@ -962,13 +982,12 @@ struct MeshBuilder {
mesh->bind();
}
void renderBuffer(Index *indices, Vertex *vertices, int iCount) {
MeshRange range;
range.iStart = 0;
range.vStart = 0;
range.iCount = iCount;
void renderBuffer(Index *indices, int iCount, Vertex *vertices, int vCount) {
dynRange.iStart = 0;
dynRange.iCount = iCount;
mesh->render(range, indices, vertices);
dynMesh->update(indices, iCount, vertices, vCount);
dynMesh->render(dynRange);
}
void renderRoomGeometry(int roomIndex, bool transparent) {

View File

@@ -34,7 +34,7 @@ namespace UI {
return width - 1;
}
#define MAX_CHARS 1024
#define MAX_CHARS DYN_MESH_QUADS
struct {
Vertex vertices[MAX_CHARS * 4];
@@ -49,7 +49,7 @@ namespace UI {
void textEnd(IGame *game) {
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;
}
}