/* ** GL_SetDefaultState */ void GL_SetDefaultState( void ) { qglClearDepth( 1.0f ); qglCullFace(GL_FRONT); qglColor4f (1,1,1,1); GL_BindNullTextures(); if (glRefConfig.framebufferObject) GL_BindNullFramebuffers(); qglEnable(GL_TEXTURE_2D); GL_TextureMode( r_textureMode->string ); //qglShadeModel( GL_SMOOTH ); qglDepthFunc( GL_LEQUAL ); // // make sure our GL state vector is set correctly // glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE; glState.storedGlState = 0; glState.faceCulling = CT_TWO_SIDED; glState.faceCullFront = qtrue; GL_BindNullProgram(); if (glRefConfig.vertexArrayObject) qglBindVertexArray(0); qglBindBuffer(GL_ARRAY_BUFFER, 0); qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glState.currentVao = NULL; glState.vertexAttribsEnabled = 0; qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglDepthMask( GL_TRUE ); qglDisable( GL_DEPTH_TEST ); qglEnable( GL_SCISSOR_TEST ); qglDisable( GL_CULL_FACE ); qglDisable( GL_BLEND ); if (glRefConfig.seamlessCubeMap) qglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); // GL_POLYGON_OFFSET_FILL will be glEnable()d when this is used qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value ); qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); // FIXME: get color of sky }
/* ============ R_BindVao ============ */ void R_BindVao(vao_t * vao) { if(!vao) { //R_BindNullVao(); ri.Error(ERR_DROP, "R_BindVao: NULL vao"); return; } if(r_logFile->integer) { // don't just call LogComment, or we will get a call to va() every frame! GLimp_LogComment(va("--- R_BindVao( %s ) ---\n", vao->name)); } if(glState.currentVao != vao) { glState.currentVao = vao; glState.vertexAttribsInterpolation = 0; glState.vertexAnimation = qfalse; backEnd.pc.c_vaoBinds++; if (glRefConfig.vertexArrayObject) { qglBindVertexArray(vao->vao); // why you no save GL_ELEMENT_ARRAY_BUFFER binding, Intel? if (1) qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO); // tess VAO always has buffers bound if (vao == tess.vao) qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO); } else { qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO); qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO); // tess VAO doesn't have vertex pointers set until data is uploaded if (vao != tess.vao) Vao_SetVertexPointers(vao); } } }
/* ============ R_BindNullVao ============ */ void R_BindNullVao(void) { GLimp_LogComment("--- R_BindNullVao ---\n"); if(glState.currentVao) { if (glRefConfig.vertexArrayObject) { qglBindVertexArray(0); // why you no save GL_ELEMENT_ARRAY_BUFFER binding, Intel? if (1) qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } else { qglBindBuffer(GL_ARRAY_BUFFER, 0); qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } glState.currentVao = NULL; } GL_CheckErrors(); }
/* ============ R_CreateVao2 ============ */ vao_t *R_CreateVao2(const char *name, int numVertexes, srfVert_t *verts, int numIndexes, glIndex_t *indexes) { vao_t *vao; int i; byte *data; int dataSize; int dataOfs; int glUsage = GL_STATIC_DRAW; if(!numVertexes || !numIndexes) return NULL; if(strlen(name) >= MAX_QPATH) { ri.Error(ERR_DROP, "R_CreateVao2: \"%s\" is too long", name); } if ( tr.numVaos == MAX_VAOS ) { ri.Error( ERR_DROP, "R_CreateVao2: MAX_VAOS hit"); } R_IssuePendingRenderCommands(); vao = tr.vaos[tr.numVaos] = ri.Hunk_Alloc(sizeof(*vao), h_low); tr.numVaos++; memset(vao, 0, sizeof(*vao)); Q_strncpyz(vao->name, name, sizeof(vao->name)); // since these vertex attributes are never altered, interleave them vao->attribs[ATTR_INDEX_POSITION ].enabled = 1; vao->attribs[ATTR_INDEX_NORMAL ].enabled = 1; #ifdef USE_VERT_TANGENT_SPACE vao->attribs[ATTR_INDEX_TANGENT ].enabled = 1; #endif vao->attribs[ATTR_INDEX_TEXCOORD ].enabled = 1; vao->attribs[ATTR_INDEX_LIGHTCOORD ].enabled = 1; vao->attribs[ATTR_INDEX_COLOR ].enabled = 1; vao->attribs[ATTR_INDEX_LIGHTDIRECTION].enabled = 1; vao->attribs[ATTR_INDEX_POSITION ].count = 3; vao->attribs[ATTR_INDEX_NORMAL ].count = 4; vao->attribs[ATTR_INDEX_TANGENT ].count = 4; vao->attribs[ATTR_INDEX_TEXCOORD ].count = 2; vao->attribs[ATTR_INDEX_LIGHTCOORD ].count = 2; vao->attribs[ATTR_INDEX_COLOR ].count = 4; vao->attribs[ATTR_INDEX_LIGHTDIRECTION].count = 4; vao->attribs[ATTR_INDEX_POSITION ].type = GL_FLOAT; vao->attribs[ATTR_INDEX_NORMAL ].type = glRefConfig.packedNormalDataType; vao->attribs[ATTR_INDEX_TANGENT ].type = glRefConfig.packedNormalDataType; vao->attribs[ATTR_INDEX_TEXCOORD ].type = glRefConfig.packedTexcoordDataType; vao->attribs[ATTR_INDEX_LIGHTCOORD ].type = glRefConfig.packedTexcoordDataType; vao->attribs[ATTR_INDEX_COLOR ].type = glRefConfig.packedColorDataType; vao->attribs[ATTR_INDEX_LIGHTDIRECTION].type = glRefConfig.packedNormalDataType; vao->attribs[ATTR_INDEX_POSITION ].normalized = GL_FALSE; vao->attribs[ATTR_INDEX_NORMAL ].normalized = GL_TRUE; vao->attribs[ATTR_INDEX_TANGENT ].normalized = GL_TRUE; vao->attribs[ATTR_INDEX_TEXCOORD ].normalized = GL_FALSE; vao->attribs[ATTR_INDEX_LIGHTCOORD ].normalized = GL_FALSE; vao->attribs[ATTR_INDEX_COLOR ].normalized = GL_FALSE; vao->attribs[ATTR_INDEX_LIGHTDIRECTION].normalized = GL_TRUE; vao->attribs[ATTR_INDEX_POSITION ].offset = 0; dataSize = sizeof(verts[0].xyz); vao->attribs[ATTR_INDEX_NORMAL ].offset = dataSize; dataSize += sizeof(uint32_t); #ifdef USE_VERT_TANGENT_SPACE vao->attribs[ATTR_INDEX_TANGENT ].offset = dataSize; dataSize += sizeof(uint32_t); #endif vao->attribs[ATTR_INDEX_TEXCOORD ].offset = dataSize; dataSize += glRefConfig.packedTexcoordDataSize; vao->attribs[ATTR_INDEX_LIGHTCOORD ].offset = dataSize; dataSize += glRefConfig.packedTexcoordDataSize; vao->attribs[ATTR_INDEX_COLOR ].offset = dataSize; dataSize += glRefConfig.packedColorDataSize; vao->attribs[ATTR_INDEX_LIGHTDIRECTION].offset = dataSize; dataSize += sizeof(uint32_t); vao->attribs[ATTR_INDEX_POSITION ].stride = dataSize; vao->attribs[ATTR_INDEX_NORMAL ].stride = dataSize; vao->attribs[ATTR_INDEX_TANGENT ].stride = dataSize; vao->attribs[ATTR_INDEX_TEXCOORD ].stride = dataSize; vao->attribs[ATTR_INDEX_LIGHTCOORD ].stride = dataSize; vao->attribs[ATTR_INDEX_COLOR ].stride = dataSize; vao->attribs[ATTR_INDEX_LIGHTDIRECTION].stride = dataSize; if (glRefConfig.vertexArrayObject) { qglGenVertexArrays(1, &vao->vao); qglBindVertexArray(vao->vao); } // create VBO dataSize *= numVertexes; data = ri.Hunk_AllocateTempMemory(dataSize); dataOfs = 0; for (i = 0; i < numVertexes; i++) { // xyz memcpy(data + dataOfs, &verts[i].xyz, sizeof(verts[i].xyz)); dataOfs += sizeof(verts[i].xyz); // normal dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].normal); #ifdef USE_VERT_TANGENT_SPACE // tangent dataOfs += R_VaoPackTangent(data + dataOfs, verts[i].tangent); #endif // texcoords dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].st); // lightmap texcoords dataOfs += R_VaoPackTexCoord(data + dataOfs, verts[i].lightmap); // colors dataOfs += R_VaoPackColors(data + dataOfs, verts[i].vertexColors); // light directions dataOfs += R_VaoPackNormal(data + dataOfs, verts[i].lightdir); } vao->vertexesSize = dataSize; qglGenBuffers(1, &vao->vertexesVBO); qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO); qglBufferData(GL_ARRAY_BUFFER, vao->vertexesSize, data, glUsage); // create IBO vao->indexesSize = numIndexes * sizeof(glIndex_t); qglGenBuffers(1, &vao->indexesIBO); qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO); qglBufferData(GL_ELEMENT_ARRAY_BUFFER, vao->indexesSize, indexes, glUsage); Vao_SetVertexPointers(vao); glState.currentVao = vao; GL_CheckErrors(); ri.Hunk_FreeTempMemory(data); return vao; }
/* ============ R_CreateVao ============ */ vao_t *R_CreateVao(const char *name, byte *vertexes, int vertexesSize, byte *indexes, int indexesSize, vaoUsage_t usage) { vao_t *vao; int glUsage; switch (usage) { case VAO_USAGE_STATIC: glUsage = GL_STATIC_DRAW; break; case VAO_USAGE_DYNAMIC: glUsage = GL_DYNAMIC_DRAW; break; default: Com_Error(ERR_FATAL, "bad vaoUsage_t given: %i", usage); return NULL; } if(strlen(name) >= MAX_QPATH) { ri.Error(ERR_DROP, "R_CreateVao: \"%s\" is too long", name); } if ( tr.numVaos == MAX_VAOS ) { ri.Error( ERR_DROP, "R_CreateVao: MAX_VAOS hit"); } R_IssuePendingRenderCommands(); vao = tr.vaos[tr.numVaos] = ri.Hunk_Alloc(sizeof(*vao), h_low); tr.numVaos++; memset(vao, 0, sizeof(*vao)); Q_strncpyz(vao->name, name, sizeof(vao->name)); if (glRefConfig.vertexArrayObject) { qglGenVertexArrays(1, &vao->vao); qglBindVertexArray(vao->vao); } vao->vertexesSize = vertexesSize; qglGenBuffers(1, &vao->vertexesVBO); qglBindBuffer(GL_ARRAY_BUFFER, vao->vertexesVBO); qglBufferData(GL_ARRAY_BUFFER, vertexesSize, vertexes, glUsage); vao->indexesSize = indexesSize; qglGenBuffers(1, &vao->indexesIBO); qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vao->indexesIBO); qglBufferData(GL_ELEMENT_ARRAY_BUFFER, indexesSize, indexes, glUsage); glState.currentVao = vao; GL_CheckErrors(); return vao; }