#include #include #include #include "../rwbase.h" #include "../rwerror.h" #include "../rwplg.h" #include "../rwrender.h" #include "../rwengine.h" #include "../rwpipeline.h" #include "../rwobjects.h" #ifdef RW_OPENGL #include #include "rwgl3.h" #include "rwgl3shader.h" #include "rwgl3impl.h" namespace rw { namespace gl3 { #define MAX_LIGHTS 8 void setAttribPointers(AttribDesc *attribDescs, int32 numAttribs) { AttribDesc *a; for(a = attribDescs; a != &attribDescs[numAttribs]; a++){ glEnableVertexAttribArray(a->index); glVertexAttribPointer(a->index, a->size, a->type, a->normalized, a->stride, (void*)(uint64)a->offset); } } void disableAttribPointers(AttribDesc *attribDescs, int32 numAttribs) { AttribDesc *a; for(a = attribDescs; a != &attribDescs[numAttribs]; a++) glDisableVertexAttribArray(a->index); } int32 lightingCB(Atomic *atomic) { WorldLights lightData; Light *directionals[8]; Light *locals[8]; lightData.directionals = directionals; lightData.numDirectionals = 8; lightData.locals = locals; lightData.numLocals = 8; if(atomic->geometry->flags & rw::Geometry::LIGHT){ ((World*)engine->currentWorld)->enumerateLights(atomic, &lightData); if((atomic->geometry->flags & rw::Geometry::NORMALS) == 0){ // Get rid of lights that need normals when we don't have any lightData.numDirectionals = 0; lightData.numLocals = 0; } return setLights(&lightData); }else{ memset(&lightData, 0, sizeof(lightData)); return setLights(&lightData); } } #define U(i) currentShader->uniformLocations[i] void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) { Material *m; RGBAf col; GLfloat surfProps[4]; setWorldMatrix(atomic->getFrame()->getLTM()); lightingCB(atomic); glBindBuffer(GL_ARRAY_BUFFER, header->vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, header->ibo); setAttribPointers(header->attribDesc, header->numAttribs); InstanceData *inst = header->inst; int32 n = header->numMeshes; defaultShader->use(); while(n--){ m = inst->material; convColor(&col, &m->color); glUniform4fv(U(u_matColor), 1, (GLfloat*)&col); surfProps[0] = m->surfaceProps.ambient; surfProps[1] = m->surfaceProps.specular; surfProps[2] = m->surfaceProps.diffuse; surfProps[3] = 0.0f; glUniform4fv(U(u_surfProps), 1, surfProps); setTexture(0, m->texture); rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF); flushCache(); glDrawElements(header->primType, inst->numIndex, GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset); inst++; } disableAttribPointers(header->attribDesc, header->numAttribs); } } } #endif