unsigned int Texture3D::GetGLName() { if(gl_name == 0) { GLDEBUG(); glDisable(GL_TEXTURE_2D); bool were_textures_enabled = glIsEnabled(GL_TEXTURE_3D) == GL_TRUE; glEnable(GL_TEXTURE_3D); glGenTextures(1, &gl_name); glBindTexture(GL_TEXTURE_3D, gl_name); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, mipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP, mipmaps ? 1 : 0); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, width, height, depth, 0, GL_RGBA, GL_UNSIGNED_BYTE, byte_data); if (!were_textures_enabled) glDisable(GL_TEXTURE_3D); GLDEBUG(); } return gl_name; }
void KRSprite::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { if(m_lod_visible >= LOD_VISIBILITY_PRESTREAM && renderPass == KRNode::RENDER_PASS_PRESTREAM) { // Pre-stream sprites, even if the alpha is zero if(m_spriteTexture.size() && m_pSpriteTexture == NULL) { if(!m_pSpriteTexture && m_spriteTexture.size()) { m_pSpriteTexture = getContext().getTextureManager()->getTexture(m_spriteTexture); } } if(m_pSpriteTexture) { m_pSpriteTexture->resetPoolExpiry(0.0f, KRTexture::TEXTURE_USAGE_SPRITE); } } if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); if(renderPass == KRNode::RENDER_PASS_ADDITIVE_PARTICLES) { if(m_spriteTexture.size() && m_spriteAlpha > 0.0f) { if(!m_pSpriteTexture && m_spriteTexture.size()) { m_pSpriteTexture = getContext().getTextureManager()->getTexture(m_spriteTexture); } if(m_pSpriteTexture) { /* // Enable additive blending GLDEBUG(glEnable(GL_BLEND)); GLDEBUG(glBlendFunc(GL_ONE, GL_ONE)); // Disable z-buffer write GLDEBUG(glDepthMask(GL_FALSE)); */ // TODO - Sprites are currently additive only. Need to expose this and allow for multiple blending modes // Enable z-buffer test GLDEBUG(glEnable(GL_DEPTH_TEST)); GLDEBUG(glDepthFunc(GL_LEQUAL)); GLDEBUG(glDepthRangef(0.0, 1.0)); // Render light sprite on transparency pass KRShader *pShader = getContext().getShaderManager()->getShader("sprite", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, getModelMatrix(), point_lights, directional_lights, spot_lights, 0, renderPass, KRVector3::Zero(), 0.0f, KRVector4::Zero())) { pShader->setUniform(KRShader::KRENGINE_UNIFORM_MATERIAL_ALPHA, m_spriteAlpha); m_pContext->getTextureManager()->selectTexture(0, m_pSpriteTexture, 0.0f, KRTexture::TEXTURE_USAGE_SPRITE); m_pContext->getMeshManager()->bindVBO(&m_pContext->getMeshManager()->KRENGINE_VBO_DATA_2D_SQUARE_VERTICES, 1.0f); GLDEBUG(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); } } } } }
bool Open(const char* path){ char* buffer; if(ReadWholeFile(buffer, path) == 0) return false; GLDEBUG(mID = OpenGL::CreateShader(GL_VERTEX_SHADER_ARB)); GLDEBUG(OpenGL::ShaderSource(mID, 1, (const GLchar**)&buffer, NULL)); GLDEBUG(OpenGL::CompileShader(mID)); delete [] buffer; return true; }
void VertexBuffer::DrawToFeedbackBuffer(VertexBuffer* target, ShaderProgram* shader_program, bool keep_fragments) { GLDEBUG(); if(!keep_fragments) glEnable(GL_RASTERIZER_DISCARD); ShaderProgram::SetActiveProgram(shader_program); GLchar const* strings[] = { "gl_Position" }; // glTransformFeedbackVaryings(shader_program->program_id, 1, strings, GL_SEPARATE_ATTRIBS); // we must re-link the program to force some things to update (i think?) glLinkProgram(shader_program->program_id); GLuint query; glGenQueries(1, &query); GLuint out_buf; glGenBuffers(1, &out_buf); glBindBuffer(GL_ARRAY_BUFFER, out_buf); glBufferData(GL_ARRAY_BUFFER, 4 * num_verts * sizeof(float), NULL, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, out_buf); // glBindVertexArray(transform vertex array name); glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query); glBeginTransformFeedback((GLenum)storage_mode); glDrawArrays((GLenum)storage_mode, 0, num_verts); glEndTransformFeedback(); glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN); glDisable(GL_RASTERIZER_DISCARD); GLuint primitives_written = 0; glGetQueryObjectuiv(query, GL_QUERY_RESULT, &primitives_written); glDeleteQueries(1, &query); /* TODO: put results into target */ GLDEBUG(); }
KRShader::~KRShader() { if(m_iProgram) { GLDEBUG(glDeleteProgram(m_iProgram)); if(getContext().getShaderManager()->m_active_shader == this) { getContext().getShaderManager()->m_active_shader = NULL; } } }
void GlowyModelMaterial::EndDraw() { ShaderProgram::SetActiveProgram(NULL); glDisable(GL_BLEND); glDisable(GL_RESCALE_NORMAL); glDepthMask(true); GLDEBUG(); }
void GlowyModelMaterial::BeginDraw(SceneRenderer* renderer) { GLDEBUG(); glDisable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glDepthMask(false); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR); glColor4f(1.0, 1.0, 1.0, 1.0); if(imp->is_3d) imp->shader->SetUniform<Texture3D>("texture", (Texture3D*)imp->tex); else imp->shader->SetUniform<Texture2D>("texture", (Texture2D*)imp->tex); ShaderProgram::SetActiveProgram(imp->shader); GLDEBUG(); }
unsigned int Texture1D::GetGLName() { if(gl_name == 0) { GLDEBUG(); glGenTextures(1, &gl_name); glEnable(GL_TEXTURE_1D); glBindTexture(GL_TEXTURE_1D, gl_name); glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, byte_data); glDisable(GL_TEXTURE_1D); GLDEBUG(); } return gl_name; }
void VertexBuffer::BuildVBO() { GLDEBUG(); vector<VertexAttribute> attribs = GetAttributes(); int total_size = GetVertexSize(); InvalidateVBO(); // just in case... // generate a vbo glGenBuffers(1, &vbo_id); glBindBuffer(GL_ARRAY_BUFFER, vbo_id); // set the total size (based on the value we computed earlier) glBufferData(GL_ARRAY_BUFFER, total_size * num_verts, NULL, GL_STATIC_DRAW); int offset = 0; for(unsigned int i = 0; i < attribs.size(); ++i) { VertexAttribute attrib = attribs[i]; int attrib_size = 0; if(attrib.type == Float) attrib_size = sizeof(float) * attrib.n_per_vertex; if(attrib_size > 0) { if(attrib.type == Float) glBufferSubData(GL_ARRAY_BUFFER, offset * num_verts, attrib_size * num_verts, attribute_data[attrib.name].floats); offset += attrib_size; } } glBindBuffer(GL_ARRAY_BUFFER, 0); // don't leave hardware vbo on GLDEBUG(); }
void KRShader::setUniform(int location, const KRVector4 &value) { if(m_uniforms[location] != -1) { int value_index = m_uniform_value_index[location]; bool needs_update = true; if(value_index == -1) { m_uniform_value_index[location] = m_uniform_value_vector4.size(); m_uniform_value_vector4.push_back(value); } else if(m_uniform_value_vector4[value_index] == value) { needs_update = false; } else { m_uniform_value_vector4[value_index] = value; } if(needs_update) { GLDEBUG(glUniform4f(m_uniforms[location], value.x, value.y, value.z, value.w)); } } }
void KRShader::setUniform(int location, const KRMat4 &value) { if(m_uniforms[location] != -1) { int value_index = m_uniform_value_index[location]; bool needs_update = true; if(value_index == -1) { m_uniform_value_index[location] = m_uniform_value_mat4.size(); m_uniform_value_mat4.push_back(value); } else if(m_uniform_value_mat4[value_index] == value) { needs_update = false; } else { m_uniform_value_mat4[value_index] = value; } if(needs_update) { GLDEBUG(glUniformMatrix4fv(m_uniforms[location], 1, GL_FALSE, value.c)); } } }
void KRShader::setUniform(int location, int value) { if(m_uniforms[location] != -1) { int value_index = m_uniform_value_index[location]; bool needs_update = true; if(value_index == -1) { m_uniform_value_index[location] = m_uniform_value_int.size(); m_uniform_value_int.push_back(value); } else if(m_uniform_value_int[value_index] == value) { needs_update = false; } else { m_uniform_value_int[value_index] = value; } if(needs_update) { GLDEBUG(glUniform1i(m_uniforms[location], value)); } } }
void KRAudioSource::render(KRCamera *pCamera, std::vector<KRPointLight *> &point_lights, std::vector<KRDirectionalLight *> &directional_lights, std::vector<KRSpotLight *>&spot_lights, const KRViewport &viewport, KRNode::RenderPass renderPass) { if(m_lod_visible <= LOD_VISIBILITY_PRESTREAM) return; KRNode::render(pCamera, point_lights, directional_lights, spot_lights, viewport, renderPass); bool bVisualize = false; if(renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT && bVisualize) { Matrix4 sphereModelMatrix = getModelMatrix(); KRShader *pShader = getContext().getShaderManager()->getShader("visualize_overlay", pCamera, point_lights, directional_lights, spot_lights, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass); if(getContext().getShaderManager()->selectShader(*pCamera, pShader, viewport, sphereModelMatrix, point_lights, directional_lights, spot_lights, 0, renderPass, Vector3::Zero(), 0.0f, Vector4::Zero())) { // Enable additive blending GLDEBUG(glEnable(GL_BLEND)); GLDEBUG(glBlendFunc(GL_ONE, GL_ONE)); // Disable z-buffer write GLDEBUG(glDepthMask(GL_FALSE)); // Enable z-buffer test GLDEBUG(glEnable(GL_DEPTH_TEST)); GLDEBUG(glDepthFunc(GL_LEQUAL)); GLDEBUG(glDepthRangef(0.0, 1.0)); std::vector<KRMesh *> sphereModels = getContext().getMeshManager()->getModel("__sphere"); if(sphereModels.size()) { for(int i=0; i < sphereModels[0]->getSubmeshCount(); i++) { sphereModels[0]->renderSubmesh(i, renderPass, getName(), "visualize_overlay", 1.0f); } } // Enable alpha blending GLDEBUG(glEnable(GL_BLEND)); GLDEBUG(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); } } }
Surface *surface_new(unsigned int w, unsigned int h, unsigned int texw, unsigned int texh, SurfaceFormat format, void *pixels, Surface *current_from, Surface *current_on) { Surface *s = new0(Surface, 1); s->w = w; s->h = h; s->texw = texw; s->texh = texh; s->filter = FILTER_DEFAULT; glGenTextures(1, &(s->tex)); glBindTexture(GL_TEXTURE_2D, s->tex); glTexImage2D(GL_TEXTURE_2D, 0, format, s->texw, s->texh, 0, format, GL_UNSIGNED_BYTE, 0); if (pixels) { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, s->w, s->h, format, GL_UNSIGNED_BYTE, pixels); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, s->filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, s->filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D, current_from ? current_from->tex : 0); if (!pixels) { // we'll need a FBO anyway surface_create_fbo(s); // We do not need to bind the fbo since it is done in create_fbo // clear the surface glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER, current_on ? current_on->fbo : 0); } GLDEBUG(); return s; }
void surface_get_pixel(Surface *s, unsigned int x, unsigned int y, int *red, int *green, int *blue, int *alpha, Surface *current_on) { assert(s); assert(red); assert(green); assert(blue); assert(alpha); assert(current_on); assert(s != current_on); if (!s->pixels_valid) { surface_draw_on(s); s->pixels_valid = true; if (!s->pixels) s->pixels = new(unsigned char, s->w * s->h * 4); glReadPixels(0, 0, s->w, s->h, GL_RGBA, GL_UNSIGNED_BYTE, s->pixels); GLDEBUG(); surface_draw_on(current_on); }
KRShader::KRShader(KRContext &context, char *szKey, std::string options, std::string vertShaderSource, const std::string fragShaderSource) : KRContextObject(context) { strcpy(m_szKey, szKey); m_iProgram = 0; GLuint vertexShader = 0, fragShader = 0; try { const GLchar *vertSource[2] = {options.c_str(), vertShaderSource.c_str()}; const GLchar *fragSource[2] = {options.c_str(), fragShaderSource.c_str()}; // Create shader program. GLDEBUG(m_iProgram = glCreateProgram()); // Create and compile vertex shader. GLDEBUG(vertexShader = glCreateShader(GL_VERTEX_SHADER)); GLDEBUG(glShaderSource(vertexShader, 2, vertSource, NULL)); GLDEBUG(glCompileShader(vertexShader)); // Report any compile issues to stderr GLint logLength; GLDEBUG(glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength)); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength + 1); assert(log != NULL); GLDEBUG(glGetShaderInfoLog(vertexShader, logLength, &logLength, log)); log[logLength] = '\0'; KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to compile vertex shader: %s\nShader compile log:\n%s", szKey, log); free(log); } // Create and compile vertex shader. GLDEBUG(fragShader = glCreateShader(GL_FRAGMENT_SHADER)); GLDEBUG(glShaderSource(fragShader, 2, fragSource, NULL)); GLDEBUG(glCompileShader(fragShader)); // Report any compile issues to stderr GLDEBUG(glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength)); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength + 1); assert(log != NULL); GLDEBUG(glGetShaderInfoLog(fragShader, logLength, &logLength, log)); log[logLength] = '\0'; KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to compile fragment shader: %s\nShader compile log:\n%s", szKey, log); free(log); } // Attach vertex shader to program. GLDEBUG(glAttachShader(m_iProgram, vertexShader)); // Attach fragment shader to program. GLDEBUG(glAttachShader(m_iProgram, fragShader)); // Bind attribute locations. // This needs to be done prior to linking. GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_VERTEX, "vertex_position")); GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_NORMAL, "vertex_normal")); GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_TANGENT, "vertex_tangent")); GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_TEXUVA, "vertex_uv")); GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_TEXUVB, "vertex_lightmap_uv")); GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_BONEINDEXES, "bone_indexes")); GLDEBUG(glBindAttribLocation(m_iProgram, KRMesh::KRENGINE_ATTRIB_BONEWEIGHTS, "bone_weights")); // Link program. GLDEBUG(glLinkProgram(m_iProgram)); GLint link_success = GL_FALSE; GLDEBUG(glGetProgramiv(m_iProgram, GL_LINK_STATUS, &link_success)); if(link_success != GL_TRUE) { // Report any linking issues to stderr KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to link shader program: %s", szKey); GLDEBUG(glGetProgramiv(m_iProgram, GL_INFO_LOG_LENGTH, &logLength)); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength + 1); assert(log != NULL); GLDEBUG(glGetProgramInfoLog(m_iProgram, logLength, &logLength, log)); log[logLength] = '\0'; KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Program link log:\n%s", log); free(log); } GLDEBUG(glDeleteProgram(m_iProgram)); m_iProgram = 0; } else { // Get uniform locations for(int i=0; i < KRENGINE_NUM_UNIFORMS; i++ ){ GLDEBUG(m_uniforms[i] = glGetUniformLocation(m_iProgram, KRENGINE_UNIFORM_NAMES[i])); m_uniform_value_index[i] = -1; } } } catch(...) { if(vertexShader) { GLDEBUG(glDeleteShader(vertexShader)); vertexShader = 0; } if(fragShader) { GLDEBUG(glDeleteShader(fragShader)); fragShader = 0; } if(m_iProgram) { GLDEBUG(glDeleteProgram(m_iProgram)); m_iProgram = 0; } } // Release vertex and fragment shaders. if (vertexShader) { GLDEBUG(glDeleteShader(vertexShader)); } if (fragShader) { GLDEBUG(glDeleteShader(fragShader)); } }
void KRVector3::setUniform(GLint location) const { if(location != -1) GLDEBUG(glUniform3f(location, x, y, z)); }
void VertexBuffer::Draw() { BuildMultiTexNames(); GLDEBUG(); unsigned int vbo = GetVBO(); vector<VertexAttribute> attribs = GetAttributes(); /* * First, we set everything up for our VBO draw operation... */ glBindBuffer(GL_ARRAY_BUFFER, vbo); int offset = 0; for(unsigned int i = 0; i < attribs.size(); ++i) { VertexAttribute attrib = attribs[i]; if(attrib.name.length() >= 3 && attrib.name.substr(0, 3) == "gl_") { if(attrib.name == "gl_Vertex") { glEnable(GL_VERTEX_ARRAY); glVertexPointer(attrib.n_per_vertex, (GLenum)attrib.type, 0, (void*)(num_verts * offset)); } else if(attrib.name == "gl_Normal") { glEnable(GL_NORMAL_ARRAY); glNormalPointer((GLenum)attrib.type, 0, (void*)(num_verts * offset)); } else if(attrib.name == "gl_Color") { glEnable(GL_COLOR_ARRAY); glColorPointer(attrib.n_per_vertex, (GLenum)attrib.type, 0, (void*)(num_verts * offset)); } else { int max_texture_units; glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_units); for(int j = 0; j < max_texture_units; ++j) { if(attrib.name == multi_tex_names[j]) { glClientActiveTexture(GL_TEXTURE0 + j); glEnable(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(attrib.n_per_vertex, (GLenum)attrib.type, 0, (void*)(num_verts * offset)); } } } } else { ShaderProgram* shader = ShaderProgram::GetActiveProgram(); if(shader != NULL) { GLuint index = (GLuint)glGetAttribLocation(shader->program_id, attrib.name.c_str()); glEnableVertexAttribArray(index); glVertexAttribPointer(index, attrib.n_per_vertex, (GLenum)attrib.type, true, 0, (void*)(num_verts * offset)); } } if(attrib.type == Float) offset += attrib.n_per_vertex * sizeof(float); } /* * Now for the draw call itself... */ glDrawArrays((GLenum)storage_mode, 0, num_verts); /* * Now to put everything back the way we found it... */ for(unsigned int i = 0; i < attribs.size(); ++i) { VertexAttribute attrib = attribs[i]; if(attrib.name.length() >= 3 && attrib.name.substr(0, 3) == "gl_") { if(attrib.name == "gl_Vertex") glDisable(GL_VERTEX_ARRAY); else if(attrib.name == "gl_Normal") glDisable(GL_NORMAL_ARRAY); else if(attrib.name == "gl_Color") glDisable(GL_COLOR_ARRAY); else { int max_texture_units; glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_units); for(int j = 0; j < max_texture_units; ++j) { if(attrib.name == multi_tex_names[j]) { glClientActiveTexture(GL_TEXTURE0 + j); glDisable(GL_TEXTURE_COORD_ARRAY); } } } } else { ShaderProgram* shader = ShaderProgram::GetActiveProgram(); if(shader != NULL) { GLuint index = (GLuint)glGetAttribLocation(shader->program_id, attrib.name.c_str()); glDisableVertexAttribArray(index); } } } glClientActiveTexture(GL_TEXTURE0); // get texcoords back to working "the normal way" glBindBuffer(GL_ARRAY_BUFFER, 0); // don't leave hardware vbo on GLDEBUG(); }
bool KRShader::bind(KRCamera &camera, const KRViewport &viewport, const KRMat4 &matModel, const std::vector<KRPointLight *> &point_lights, const std::vector<KRDirectionalLight *> &directional_lights, const std::vector<KRSpotLight *>&spot_lights, const KRNode::RenderPass &renderPass, const KRVector3 &rim_color, float rim_power, const KRVector4 &fade_color) { if(m_iProgram == 0) { return false; } bool shander_changed = false; if(getContext().getShaderManager()->m_active_shader != this) { getContext().getShaderManager()->m_active_shader = this; GLDEBUG(glUseProgram(m_iProgram)); shander_changed = true; } setUniform(KRENGINE_UNIFORM_ABSOLUTE_TIME, getContext().getAbsoluteTime()); int light_directional_count = 0; int light_point_count = 0; int light_spot_count = 0; // TODO - Need to support multiple lights and more light types in forward rendering if(renderPass != KRNode::RENDER_PASS_DEFERRED_LIGHTS && renderPass != KRNode::RENDER_PASS_DEFERRED_GBUFFER && renderPass != KRNode::RENDER_PASS_DEFERRED_OPAQUE && renderPass != KRNode::RENDER_PASS_GENERATE_SHADOWMAPS) { for(std::vector<KRDirectionalLight *>::const_iterator light_itr=directional_lights.begin(); light_itr != directional_lights.end(); light_itr++) { KRDirectionalLight *directional_light = (*light_itr); if(light_directional_count == 0) { int cShadowBuffers = directional_light->getShadowBufferCount(); if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE1] != -1 && cShadowBuffers > 0) { if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 3, directional_light->getShadowTextures()[0])) { GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); } m_pContext->getTextureManager()->_setWrapModeS(3, GL_CLAMP_TO_EDGE); m_pContext->getTextureManager()->_setWrapModeT(3, GL_CLAMP_TO_EDGE); } if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE2] != -1 && cShadowBuffers > 1 && camera.settings.m_cShadowBuffers > 1) { if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 4, directional_light->getShadowTextures()[1])) { GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); } m_pContext->getTextureManager()->_setWrapModeS(4, GL_CLAMP_TO_EDGE); m_pContext->getTextureManager()->_setWrapModeT(4, GL_CLAMP_TO_EDGE); } if(m_uniforms[KRENGINE_UNIFORM_SHADOWTEXTURE3] != -1 && cShadowBuffers > 2 && camera.settings.m_cShadowBuffers > 2) { if(m_pContext->getTextureManager()->selectTexture(GL_TEXTURE_2D, 5, directional_light->getShadowTextures()[2])) { GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); } m_pContext->getTextureManager()->_setWrapModeS(5, GL_CLAMP_TO_EDGE); m_pContext->getTextureManager()->_setWrapModeT(5, GL_CLAMP_TO_EDGE); } KRMat4 matBias; matBias.translate(1.0, 1.0, 1.0); matBias.scale(0.5); for(int iShadow=0; iShadow < cShadowBuffers; iShadow++) { setUniform(KRENGINE_UNIFORM_SHADOWMVP1 + iShadow, matModel * directional_light->getShadowViewports()[iShadow].getViewProjectionMatrix() * matBias); } if(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE] != -1) { KRMat4 inverseModelMatrix = matModel; inverseModelMatrix.invert(); // Bind the light direction vector KRVector3 lightDirObject = KRMat4::Dot(inverseModelMatrix, directional_light->getWorldLightDirection()); lightDirObject.normalize(); setUniform(KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE, lightDirObject); } } light_directional_count++; } light_point_count = point_lights.size(); light_spot_count = spot_lights.size(); } if(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] != -1) { KRMat4 inverseModelMatrix = matModel; inverseModelMatrix.invert(); if(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] != -1) { // Transform location of camera to object space for calculation of specular halfVec KRVector3 cameraPosObject = KRMat4::Dot(inverseModelMatrix, viewport.getCameraPosition()); setUniform(KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE, cameraPosObject); } } if(m_uniforms[KRENGINE_UNIFORM_MVP] != -1 || m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP] != -1) { // Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram KRMat4 mvpMatrix = matModel * viewport.getViewProjectionMatrix(); setUniform(KRENGINE_UNIFORM_MVP, mvpMatrix); if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP] != -1) { setUniform(KRShader::KRENGINE_UNIFORM_INVMVP, KRMat4::Invert(mvpMatrix)); } } if(m_uniforms[KRShader::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN] != -1 || m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1 || m_uniforms[KRShader::KRENGINE_UNIFORM_MODEL_VIEW] != -1) { KRMat4 matModelView = matModel * viewport.getViewMatrix(); setUniform(KRENGINE_UNIFORM_MODEL_VIEW, matModelView); if(m_uniforms[KRShader::KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN] != -1) { KRVector3 view_space_model_origin = KRMat4::Dot(matModelView, KRVector3::Zero()); // Origin point of model space is the light source position. No perspective, so no w divide required setUniform(KRENGINE_UNIFORM_VIEW_SPACE_MODEL_ORIGIN, view_space_model_origin); } if(m_uniforms[KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE] != -1) { KRMat4 matModelViewInverseTranspose = matModelView; matModelViewInverseTranspose.transpose(); matModelViewInverseTranspose.invert(); setUniform(KRENGINE_UNIFORM_MODEL_VIEW_INVERSE_TRANSPOSE, matModelViewInverseTranspose); } } if(m_uniforms[KRENGINE_UNIFORM_MODEL_INVERSE_TRANSPOSE] != -1) { KRMat4 matModelInverseTranspose = matModel; matModelInverseTranspose.transpose(); matModelInverseTranspose.invert(); setUniform(KRENGINE_UNIFORM_MODEL_INVERSE_TRANSPOSE, matModelInverseTranspose); } if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVP] != -1) { setUniform(KRENGINE_UNIFORM_INVP, viewport.getInverseProjectionMatrix()); } if(m_uniforms[KRShader::KRENGINE_UNIFORM_INVMVP_NO_TRANSLATE] != -1) { KRMat4 matInvMVPNoTranslate = matModel * viewport.getViewMatrix();; // Remove the translation matInvMVPNoTranslate.getPointer()[3] = 0; matInvMVPNoTranslate.getPointer()[7] = 0; matInvMVPNoTranslate.getPointer()[11] = 0; matInvMVPNoTranslate.getPointer()[12] = 0; matInvMVPNoTranslate.getPointer()[13] = 0; matInvMVPNoTranslate.getPointer()[14] = 0; matInvMVPNoTranslate.getPointer()[15] = 1.0; matInvMVPNoTranslate = matInvMVPNoTranslate * viewport.getProjectionMatrix(); matInvMVPNoTranslate.invert(); setUniform(KRENGINE_UNIFORM_INVMVP_NO_TRANSLATE, matInvMVPNoTranslate); } setUniform(KRENGINE_UNIFORM_MODEL_MATRIX, matModel); if(m_uniforms[KRENGINE_UNIFORM_PROJECTION_MATRIX] != -1) { setUniform(KRENGINE_UNIFORM_PROJECTION_MATRIX, viewport.getProjectionMatrix()); } if(m_uniforms[KRENGINE_UNIFORM_VIEWPORT] != -1) { setUniform(KRENGINE_UNIFORM_VIEWPORT, KRVector4( (GLfloat)0.0, (GLfloat)0.0, (GLfloat)viewport.getSize().x, (GLfloat)viewport.getSize().y ) ); } if(m_uniforms[KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE] != -1) { setUniform(KRENGINE_UNIFORM_VIEWPORT_DOWNSAMPLE, camera.getDownsample()); } // Rim highlighting parameters setUniform(KRENGINE_UNIFORM_RIM_COLOR, rim_color); setUniform(KRENGINE_UNIFORM_RIM_POWER, rim_power); // Fade parameters setUniform(KRENGINE_UNIFORM_FADE_COLOR, fade_color); // Fog parameters setUniform(KRENGINE_UNIFORM_FOG_NEAR, camera.settings.fog_near); setUniform(KRENGINE_UNIFORM_FOG_FAR, camera.settings.fog_far); setUniform(KRENGINE_UNIFORM_FOG_DENSITY, camera.settings.fog_density); setUniform(KRENGINE_UNIFORM_FOG_COLOR, camera.settings.fog_color); if(m_uniforms[KRENGINE_UNIFORM_FOG_SCALE] != -1) { setUniform(KRENGINE_UNIFORM_FOG_SCALE, 1.0f / (camera.settings.fog_far - camera.settings.fog_near)); } if(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL] != -1) { setUniform(KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_EXPONENTIAL, -camera.settings.fog_density * 1.442695f); // -fog_density / log(2) } if(m_uniforms[KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED] != -1) { setUniform(KRENGINE_UNIFORM_DENSITY_PREMULTIPLIED_SQUARED, (float)(-camera.settings.fog_density * camera.settings.fog_density * 1.442695)); // -fog_density * fog_density / log(2) } // Sets the diffuseTexture variable to the first texture unit setUniform(KRENGINE_UNIFORM_DIFFUSETEXTURE, 0); // Sets the specularTexture variable to the second texture unit setUniform(KRENGINE_UNIFORM_SPECULARTEXTURE, 1); // Sets the normalTexture variable to the third texture unit setUniform(KRENGINE_UNIFORM_NORMALTEXTURE, 2); // Sets the shadowTexture variable to the fourth texture unit setUniform(KRENGINE_UNIFORM_SHADOWTEXTURE1, 3); setUniform(KRENGINE_UNIFORM_SHADOWTEXTURE2, 4); setUniform(KRENGINE_UNIFORM_SHADOWTEXTURE3, 5); setUniform(KRENGINE_UNIFORM_REFLECTIONCUBETEXTURE, 4); setUniform(KRENGINE_UNIFORM_LIGHTMAPTEXTURE, 5); setUniform(KRENGINE_UNIFORM_GBUFFER_FRAME, 6); setUniform(KRENGINE_UNIFORM_GBUFFER_DEPTH, 7); // Texture unit 7 is used for reading the depth buffer in gBuffer pass #2 and in post-processing pass setUniform(KRENGINE_UNIFORM_REFLECTIONTEXTURE, 7); // Texture unit 7 is used for the reflection map textures in gBuffer pass #3 and when using forward rendering setUniform(KRENGINE_UNIFORM_DEPTH_FRAME, 0); setUniform(KRENGINE_UNIFORM_RENDER_FRAME, 1); setUniform(KRENGINE_UNIFORM_VOLUMETRIC_ENVIRONMENT_FRAME, 2); #if defined(DEBUG) if(shander_changed) { // FINDME!! KIP!! HACK!! GLint logLength; GLint validate_status = GL_FALSE; GLDEBUG(glValidateProgram(m_iProgram)); GLDEBUG(glGetProgramiv(m_iProgram, GL_VALIDATE_STATUS, &validate_status)); if(validate_status != GL_TRUE) { KRContext::Log(KRContext::LOG_LEVEL_ERROR, "KREngine - Failed to validate shader program: %s", m_szKey); GLDEBUG(glGetProgramiv(m_iProgram, GL_INFO_LOG_LENGTH, &logLength)); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength + 1); assert(log != NULL); GLDEBUG(glGetProgramInfoLog(m_iProgram, logLength, &logLength, log)); log[logLength] = '\0'; KRContext::Log(KRContext::LOG_LEVEL_ERROR, "Program validate log:\n%s", log); free(log); } return false; } } #endif return true; }
void KRVector2::setUniform(GLint location) const { if(location != -1) GLDEBUG(glUniform2f(location, x, y)); }