Beispiel #1
0
	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;
	}
Beispiel #2
0
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));
                }
            }
        }
        
    }
}
Beispiel #3
0
	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;
	}
Beispiel #4
0
	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();
	}
Beispiel #5
0
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();
	}
Beispiel #8
0
	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;
	}
Beispiel #9
0
	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();
	}
Beispiel #10
0
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));
        }
    }
}
Beispiel #11
0
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));
        }
    }
}
Beispiel #12
0
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));
        }
    }
}
Beispiel #13
0
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));
        }
    }
}
Beispiel #14
0
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;
}
Beispiel #15
0
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);
    }
Beispiel #16
0
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));
	}
}
Beispiel #17
0
void KRVector3::setUniform(GLint location) const
{
    if(location != -1) GLDEBUG(glUniform3f(location, x, y, z));
}
Beispiel #18
0
	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();
	}
Beispiel #19
0
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;
}
Beispiel #20
0
void KRVector2::setUniform(GLint location) const
{
    if(location != -1) GLDEBUG(glUniform2f(location, x, y));
}