Add textured materials to render context, and refactor mjvGeom to refer to those textures.

PiperOrigin-RevId: 648719103
Change-Id: Idb4425bdeea3cbc1133cda3e4366574ed3bb5ccc
This commit is contained in:
Tom Erez
2024-07-02 08:00:06 -07:00
committed by Copybara-Service
parent af3233f98d
commit 3b73dfe33b
14 changed files with 252 additions and 195 deletions
+3 -14
View File
@@ -302,21 +302,13 @@ static void setMaterial(const mjModel* m, mjvGeom* geom, int matid, const float*
const mjtByte* flags) {
// set material properties if given
if (matid >= 0) {
f2f(geom->texrepeat, m->mat_texrepeat + 2*matid, 2);
f2f(geom->rgba, m->mat_rgba + 4*matid, 4);
geom->texuniform = m->mat_texuniform[matid];
geom->emission = m->mat_emission[matid];
geom->specular = m->mat_specular[matid];
geom->shininess = m->mat_shininess[matid];
geom->reflectance = m->mat_reflectance[matid];
}
// otherwise clear texrepeat
else {
geom->texrepeat[0] = 0;
geom->texrepeat[1] = 0;
}
// use rgba if different from default, or no material given
if (rgba[0] != 0.5f || rgba[1] != 0.5f || rgba[2] != 0.5f || rgba[3] != 1.0f || matid < 0) {
f2f(geom->rgba, rgba, 4);
@@ -324,7 +316,7 @@ static void setMaterial(const mjModel* m, mjvGeom* geom, int matid, const float*
// set texture
if (flags[mjVIS_TEXTURE] && matid >= 0) {
geom->texid = m->mat_texid[matid];
geom->matid = matid;
}
// scale alpha for dynamic geoms only
@@ -458,11 +450,8 @@ void mjv_initGeom(mjvGeom* geom, int type, const mjtNum* size,
// set defaults that cannot be assigned via this function
geom->dataid = -1;
geom->texid = -1;
geom->texuniform = 0;
geom->matid = -1;
geom->texcoord = 0;
geom->texrepeat[0] = 1;
geom->texrepeat[1] = 1;
geom->emission = 0;
geom->specular = 0.5;
geom->shininess = 0.5;
@@ -571,7 +560,7 @@ void mjv_addGeoms(const mjModel* m, mjData* d, const mjvOption* vopt,
thisgeom->texcoord = 1;
}
else {
thisgeom->texid = -1;
thisgeom->matid = -1;
}
// glow flex if selected
+32
View File
@@ -1294,6 +1294,37 @@ static void makeFont(mjrContext* con, int fontscale) {
}
}
// make materials, just for those that have textures
static void makeMaterial(const mjModel* m, mjrContext* con) {
memset(con->mat_texid, -1, sizeof(con->mat_texid));
memset(con->mat_texuniform, 0, sizeof(con->mat_texuniform));
memset(con->mat_texrepeat, 0, sizeof(con->mat_texrepeat));
if (!m->nmat || !m->ntex) {
return;
}
if (m->nmat >= mjMAXMATERIAL-1) {
mju_error("Maximum number of materials is %d", mjMAXMATERIAL);
}
for (int i=0; i < m->nmat; i++) {
if (m->mat_texid[i] >= 0) {
con->mat_texid[i*mjNTEXMAT] = m->mat_texid[i];
con->mat_texuniform[i] = m->mat_texuniform[i];
con->mat_texrepeat[2*i] = m->mat_texrepeat[2*i];
con->mat_texrepeat[2*i+1] = m->mat_texrepeat[2*i+1];
}
}
// find skybox texture
for (int i=0; i < m->ntex; i++) {
if (m->tex_type[i] == mjTEXTURE_SKYBOX) {
if (m->nmat >= mjMAXMATERIAL-2) {
mju_error("With skybox, maximum number of materials is %d", mjMAXMATERIAL);
}
con->mat_texid[mjNTEXMAT * (mjMAXMATERIAL-1)] = i;
break;
}
}
}
// make textures
@@ -1585,6 +1616,7 @@ void mjr_makeContext_offSize(const mjModel* m, mjrContext* con, int fontscale,
// make everything
makeOff(con);
makeShadow(m, con);
makeMaterial(m, con);
makeTexture(m, con);
makePlane(m, con);
makeMesh(m, con);
+19 -15
View File
@@ -61,6 +61,10 @@ enum {
// enable/disable texture mapping
static void settexture(int type, int state, const mjrContext* con, const mjvGeom* geom) {
float plane[4], scl[2];
int texid = -1;
if (geom) {
texid = (geom->matid == -1) ? -1 : con->mat_texid[mjNTEXMAT * geom->matid];
}
// shadow
if (type == mjtexSHADOW) {
@@ -92,7 +96,7 @@ static void settexture(int type, int state, const mjrContext* con, const mjvGeom
if (state) {
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, con->texture[geom->texid]);
glBindTexture(GL_TEXTURE_2D, con->texture[texid]);
}
// disable
@@ -103,18 +107,18 @@ static void settexture(int type, int state, const mjrContext* con, const mjvGeom
}
// 2D
else if (type == mjtexREGULAR && con->textureType[geom->texid] == mjTEXTURE_2D) {
else if (type == mjtexREGULAR && con->textureType[texid] == mjTEXTURE_2D) {
// enable
if (state) {
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glBindTexture(GL_TEXTURE_2D, con->texture[geom->texid]);
glBindTexture(GL_TEXTURE_2D, con->texture[texid]);
// determine scaling, adjust for pre-scaled geoms
scl[0] = geom->texrepeat[0];
scl[1] = geom->texrepeat[1];
scl[0] = con->mat_texrepeat[geom->matid*2];
scl[1] = con->mat_texrepeat[geom->matid*2+1];
if (geom->dataid >= 0) {
if (geom->size[0] > 0) {
scl[0] = scl[0] / mju_max(mjMINVAL, geom->size[0]);
@@ -126,7 +130,7 @@ static void settexture(int type, int state, const mjrContext* con, const mjvGeom
}
// uniform: repeat relative to spatial units rather than object
if (geom->texuniform) {
if (con->mat_texuniform[geom->matid]) {
if (geom->size[0] > 0) {
scl[0] = scl[0] * geom->size[0];
}
@@ -161,15 +165,15 @@ static void settexture(int type, int state, const mjrContext* con, const mjvGeom
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glBindTexture(GL_TEXTURE_CUBE_MAP, con->texture[geom->texid]);
glBindTexture(GL_TEXTURE_CUBE_MAP, con->texture[texid]);
// set mapping : cube
if (type == mjtexREGULAR) {
mjr_setf4(plane, geom->texuniform ? geom->size[0] : 1, 0, 0, 0);
mjr_setf4(plane, con->mat_texuniform[geom->matid] ? geom->size[0] : 1, 0, 0, 0);
glTexGenfv(GL_S, GL_OBJECT_PLANE, plane);
mjr_setf4(plane, 0, geom->texuniform ? geom->size[1] : 1, 0, 0);
mjr_setf4(plane, 0, con->mat_texuniform[geom->matid] ? geom->size[1] : 1, 0, 0);
glTexGenfv(GL_T, GL_OBJECT_PLANE, plane);
mjr_setf4(plane, 0, 0, geom->texuniform ? geom->size[2] : 1, 0);
mjr_setf4(plane, 0, 0, con->mat_texuniform[geom->matid] ? geom->size[2] : 1, 0);
glTexGenfv(GL_R, GL_OBJECT_PLANE, plane);
}
@@ -232,7 +236,7 @@ static void renderGeom(const mjvGeom* geom, int mode, const float* headpos,
behind = isBehind(headpos, geom->pos, geom->mat);
// enable texture in normal and shadowmap mode
if (geom->texid >= 0 && con->ntexture > 0 &&
if (geom->matid >= 0 &&
(mode == mjrRND_NORMAL || mode == mjrRND_SHADOWMAP)) {
settexture(mjtexREGULAR, 1, con, geom);
}
@@ -515,14 +519,14 @@ static void renderGeom(const mjvGeom* geom, int mode, const float* headpos,
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, scn->flexface + 9*scn->flexfaceadr[geom->objid]);
glNormalPointer(GL_FLOAT, 0, scn->flexnormal + 9*scn->flexfaceadr[geom->objid]);
if (geom->texcoord && geom->texid>=0) {
if (geom->texcoord && geom->matid>=0) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, scn->flextexcoord + 6*scn->flexfaceadr[geom->objid]);
}
glDrawArrays(GL_TRIANGLES, 0, 3*scn->flexfaceused[geom->objid]);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
if (geom->texcoord && geom->texid>=0) {
if (geom->texcoord && geom->matid>=0) {
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
@@ -568,7 +572,7 @@ static void renderGeom(const mjvGeom* geom, int mode, const float* headpos,
glPopMatrix();
// disable texture if enabled
if (geom->texid >= 0 && con->ntexture > 0 &&
if (geom->matid >= 0 &&
(mode == mjrRND_NORMAL || mode == mjrRND_SHADOWMAP)) {
settexture(mjtexREGULAR, 0, con, geom);
}
@@ -1268,7 +1272,7 @@ void mjr_render(mjrRect viewport, mjvScene* scn, const mjrContext* con) {
if (con->textureType[i] == mjTEXTURE_SKYBOX) {
// save first skybox texture id in tempgeom
memset(&tempgeom, 0, sizeof(mjvGeom));
tempgeom.texid = i;
tempgeom.matid = mjMAXMATERIAL - 1;
// modify settings
glDisable(GL_LIGHTING);