Example #1
0
    virtual void startup()
    {
        static const GLubyte toon_tex_data[] =
        {
            0x44, 0x00, 0x00, 0x00,
            0x88, 0x00, 0x00, 0x00,
            0xCC, 0x00, 0x00, 0x00,
            0xFF, 0x00, 0x00, 0x00
        };

        glGenTextures(1, &tex_toon);
        glBindTexture(GL_TEXTURE_1D, tex_toon);
        glTexStorage1D(GL_TEXTURE_1D, 1, GL_RGB8, sizeof(toon_tex_data) / 4);
        glTexSubImage1D(GL_TEXTURE_1D, 0,
                        0, sizeof(toon_tex_data) / 4,
                        GL_RGBA, GL_UNSIGNED_BYTE,
                        toon_tex_data);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

        object.load("media/objects/torus_nrms_tc.sbm");

        load_shaders();

        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
    }
Example #2
0
    void startup()
    {
        //		_renderingProgram.CreateAndLinkProgram("Shaders/Common/Default.vert", "Shaders/Common/Default.frag");
        _renderingProgram.CreateProgram();
        _renderingProgram.AttachShader("Shaders/Cellshading/Cellshading.vert");
        _renderingProgram.AttachShader("Shaders/Cellshading/Cellshading.frag");
        _renderingProgram.Link();
        projLocation = glGetUniformLocation(_renderingProgram.GetHandler(), "proj_matrix");
        mvLocation = glGetUniformLocation(_renderingProgram.GetHandler(), "mv_matrix");

        static const GLubyte tex[] =
        {
            0x44, 0x00, 0x00, 0x00,
            0x88, 0x00, 0x00, 0x00,
            0xCC, 0x00, 0x00, 0x00,
            0xFF, 0x00, 0x00, 0x00
        };

        glGenTextures(1, &_texToon);
        glBindTexture(GL_TEXTURE_1D, _texToon);
        glTexStorage1D(GL_TEXTURE_1D, 1, GL_RGB8, sizeof(tex) / 4);
        glTexSubImage1D(GL_TEXTURE_1D, 0, 0, sizeof(tex) / 4, GL_RGBA, GL_UNSIGNED_BYTE, tex);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        
        _object.load("media/objects/torus_nrms_tc.sbm");

        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
        _renderingProgram.Use();
    }
void QOpenGLTextureHelper::qt_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width)
{
    GLint oldTexture;
    glGetIntegerv(bindingTarget, &oldTexture);
    glBindTexture(target, texture);
    glTexStorage1D(target, levels, internalFormat, width);
    glBindTexture(target, oldTexture);
}
Example #4
0
void AbstractTexture::storageImplementationDefault(GLenum target, GLsizei levels, AbstractTexture::InternalFormat internalFormat, const Math::Vector< 1, GLsizei >& size) {
    bindInternal();
    /** @todo Re-enable when extension wrangler is available for ES2 */
    #ifndef MAGNUM_TARGET_GLES2
    glTexStorage1D(target, levels, GLenum(internalFormat), size[0]);
    #else
    //glTexStorage2DEXT(target, levels, GLenum(internalFormat), size.x(), size.y());
    static_cast<void>(target);
    static_cast<void>(levels);
    static_cast<void>(internalFormat);
    static_cast<void>(size);
    #endif
}
void Texture::SetStorage(int width, int height, int depth, int levels){
	switch(type){
		case TT_GL_TEXTURE_1D:
			GLCALL(glTexStorage1D(type, levels, format, width));
			break;
		case TT_GL_TEXTURE_2D:
		case TT_GL_TEXTURE_1D_ARRAY:
		case TT_GL_TEXTURE_RECTANGLE:
		case TT_GL_TEXTURE_CUBE_MAP:
			GLCALL(glTexStorage2D(type, levels, format, width, height));
			break;

		case TT_GL_TEXTURE_3D:
		case TT_GL_TEXTURE_2D_ARRAY:
		case TT_GL_TEXTURE_CUBE_MAP_ARRAY:
			GLCALL(glTexStorage3D(type, levels, format, width, height, depth));
			break;
	}
}
Example #6
0
PlatformTexture1d::PlatformTexture1d(const Texture1d *texture) :
    PlatformTexture(texture)
{
    // Bind newly created texture
    GLuint textureBindingPrevious = BindTexture(mTexturePtr->mType, mTextureObj);

    {
        glTexStorage1D(GL_TEXTURE_1D, 1, mFormatInternal, mDimension[0]);

        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mBufferObj);

        {
            glTexSubImage1D(GL_TEXTURE_1D, 0, 0, mDimension[0], mFormat, mType, nullptr);
        }

        glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
    }

    // Restore previous texture binding
    BindTexture(mTexturePtr->mType, textureBindingPrevious);
}
Example #7
0
    void startup(void)
    {
        // Load texture from file
        tex_src = sb6::ktx::file::load("media/textures/treelights_2k.ktx");

        // Now bind it to the context using the GL_TEXTURE_2D binding point
        glBindTexture(GL_TEXTURE_2D, tex_src);

        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);

        load_shaders();

        static const GLfloat exposureLUT[20]   = { 11.0f, 6.0f, 3.2f, 2.8f, 2.2f, 1.90f, 1.80f, 1.80f, 1.70f, 1.70f,  1.60f, 1.60f, 1.50f, 1.50f, 1.40f, 1.40f, 1.30f, 1.20f, 1.10f, 1.00f };

        glGenTextures(1, &tex_lut);
        glBindTexture(GL_TEXTURE_1D, tex_lut);
        glTexStorage1D(GL_TEXTURE_1D, 1, GL_R32F, 20);
        glTexSubImage1D(GL_TEXTURE_1D, 0, 0, 20, GL_RED, GL_FLOAT, exposureLUT);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    }
Example #8
0
static bool
try_TexStorage(GLenum internalFormat)
{
	bool pass = true;
	GLuint tex[4];

	GLenum expected_error;
	GLenum expected_3D_error;
	GLenum expected_cube_error;

	/* The GL_ARB_texture_storage spec says:
	 *
	 *     "- If <internalformat> is one of the internal formats listed in
	 *      table 3.11, an INVALID_ENUM error is generated."
	 *
	 * Table 3.11 lists the unsized formats, including GL_DEPTH_STENCIL.
	 */
	if (internalFormat == GL_DEPTH_STENCIL) {
		expected_error = has_depth_texture
			? GL_INVALID_ENUM : GL_INVALID_VALUE;
		expected_3D_error = has_depth_texture
			? GL_INVALID_ENUM : GL_INVALID_VALUE;
		expected_cube_error = has_depth_texture_cube_map
			? GL_INVALID_ENUM : GL_INVALID_VALUE;
	} else {
		expected_error = has_depth_texture
			? GL_NO_ERROR : GL_INVALID_VALUE;
		expected_3D_error = has_depth_texture
			? GL_INVALID_OPERATION : GL_INVALID_VALUE;
		expected_cube_error = has_depth_texture_cube_map
			? GL_NO_ERROR : expected_3D_error;
	}

	printf("Testing glTexStorage with %s...\n",
	       piglit_get_gl_enum_name(internalFormat));

	glGenTextures(ARRAY_SIZE(tex), tex);

#if defined PIGLIT_USE_OPENGL
	glBindTexture(GL_TEXTURE_1D, tex[0]);
	glTexStorage1D(GL_TEXTURE_1D, 1, internalFormat, 16);
	pass = piglit_check_gl_error(expected_error) && pass;
#endif

	glBindTexture(GL_TEXTURE_2D, tex[1]);
	glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, 16, 16);
	pass = piglit_check_gl_error(expected_error) && pass;

#if !defined PIGLIT_USE_OPENGL_ES1
	if (has_texture_3d) {
		glBindTexture(GL_TEXTURE_3D, tex[2]);
		glTexStorage3D(GL_TEXTURE_3D, 1, internalFormat, 8, 8, 8);
		pass = piglit_check_gl_error(expected_3D_error) && pass;
	}
#else
	/* Silence "variable ‘expected_3D_error’ set but not used" warnings.
	 */
	(void) expected_3D_error;
#endif

	if (has_texture_cube_map) {
		glBindTexture(GL_TEXTURE_CUBE_MAP, tex[3]);
		glTexStorage2D(GL_TEXTURE_CUBE_MAP, 1, internalFormat, 16, 16);
		pass = piglit_check_gl_error(expected_cube_error) && pass;
	}

#if defined PIGLIT_USE_OPENGL
	glBindTexture(GL_TEXTURE_1D, 0);
#endif
	glBindTexture(GL_TEXTURE_2D, 0);
	if (has_texture_3d)
		glBindTexture(GL_TEXTURE_3D, 0);
	if (has_texture_cube_map)
		glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

	glDeleteTextures(ARRAY_SIZE(tex), tex);

	printf("Done.\n\n");

	return pass;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL42_glTexStorage1D(JNIEnv *__env, jclass clazz, jint target, jint levels, jint internalformat, jint width) {
    glTexStorage1DPROC glTexStorage1D = (glTexStorage1DPROC)tlsGetFunction(859);
    UNUSED_PARAM(clazz)
    glTexStorage1D(target, levels, internalformat, width);
}
Example #10
0
GLuint vglLoadTexture(const char* filename,
                      GLuint texture,
                      vglImageData* image)
{
    vglImageData local_image;
    int level;

    if (image == 0)
        image = &local_image;

    vglLoadImage(filename, image);

    if (texture == 0)
    {
        glGenTextures(1, &texture);
    }

    glBindTexture(image->target, texture);

    GLubyte * ptr = (GLubyte *)image->mip[0].data;

    switch (image->target)
    {
        case GL_TEXTURE_1D:
            glTexStorage1D(image->target,
                           image->mipLevels,
                           image->internalFormat,
                           image->mip[0].width);
            for (level = 0; level < image->mipLevels; ++level)
            {
                glTexSubImage1D(GL_TEXTURE_1D,
                                level,
                                0,
                                image->mip[level].width,
                                image->format, image->type,
                                image->mip[level].data);
            }
            break;
        case GL_TEXTURE_1D_ARRAY:
            glTexStorage2D(image->target,
                           image->mipLevels,
                           image->internalFormat,
                           image->mip[0].width,
                           image->slices);
            for (level = 0; level < image->mipLevels; ++level)
            {
                glTexSubImage2D(GL_TEXTURE_1D,
                                level,
                                0, 0,
                                image->mip[level].width, image->slices,
                                image->format, image->type,
                                image->mip[level].data);
            }
            break;
        case GL_TEXTURE_2D:
            glTexStorage2D(image->target,
                           image->mipLevels,
                           image->internalFormat,
                           image->mip[0].width,
                           image->mip[0].height);
            for (level = 0; level < image->mipLevels; ++level)
            {
                glTexSubImage2D(GL_TEXTURE_2D,
                                level,
                                0, 0,
                                image->mip[level].width, image->mip[level].height,
                                image->format, image->type,
                                image->mip[level].data);
            }
            break;
        case GL_TEXTURE_CUBE_MAP:
            for (level = 0; level < image->mipLevels; ++level)
            {
                ptr = (GLubyte *)image->mip[level].data;
                for (int face = 0; face < 6; face++)
                {
                    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
                                 level,
                                 image->internalFormat,
                                 image->mip[level].width, image->mip[level].height,
                                 0,
                                 image->format, image->type,
                                 ptr + image->sliceStride * face);
                }
            }
            break;
        case GL_TEXTURE_2D_ARRAY:
            glTexStorage3D(image->target,
                           image->mipLevels,
                           image->internalFormat,
                           image->mip[0].width,
                           image->mip[0].height,
                           image->slices);
            for (level = 0; level < image->mipLevels; ++level)
            {
                glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
                                level,
                                0, 0, 0,
                                image->mip[level].width, image->mip[level].height, image->slices,
                                image->format, image->type,
                                image->mip[level].data);
            }
            break;
        case GL_TEXTURE_CUBE_MAP_ARRAY:
            glTexStorage3D(image->target,
                           image->mipLevels,
                           image->internalFormat,
                           image->mip[0].width,
                           image->mip[0].height,
                           image->slices);
            break;
        case GL_TEXTURE_3D:
            glTexStorage3D(image->target,
                           image->mipLevels,
                           image->internalFormat,
                           image->mip[0].width,
                           image->mip[0].height,
                           image->mip[0].depth);
            for (level = 0; level < image->mipLevels; ++level)
            {
                glTexSubImage3D(GL_TEXTURE_3D,
                                level,
                                0, 0, 0,
                                image->mip[level].width, image->mip[level].height, image->mip[level].depth,
                                image->format, image->type,
                                image->mip[level].data);
            }
            break;
        default:
            break;
    }

    glTexParameteriv(image->target, GL_TEXTURE_SWIZZLE_RGBA, reinterpret_cast<const GLint *>(image->swizzle));

    if (image == &local_image)
    {
        vglUnloadImage(image);
    }

    return texture;
}
Example #11
0
static bool
test_format_lifetime(const struct format_desc desc0,
		     const struct format_desc desc1)
{
	GLuint tex, viewTex[3];
	GLint width = 32, w, levels = 6;
	GLint l;
	int bytes;
	unsigned char *buffer0, *buffer1;
	bool pass = true;

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_1D, tex);
	glTexStorage1D(GL_TEXTURE_1D, levels, desc0.storagefmt, width);
	glGenTextures(3, viewTex);
	glTextureView(viewTex[0], GL_TEXTURE_1D, tex,  desc0.internalfmt, 0,
			  levels, 0, 1);
	glTextureView(viewTex[1], GL_TEXTURE_1D, viewTex[0],
		      desc1.internalfmt, 0, levels, 0, 1);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	/* load each mipmap with a different color texture */
	w = width;
	bytes = (desc0.red + desc0.green + desc0.blue + desc0.alpha) / 8;
	for (l = 0; l < levels; l++) {
		GLubyte *buf = create_solid_image(width, 1, 1, bytes, l);

		if (buf != NULL) {
			glTexSubImage1D(GL_TEXTURE_1D, l, 0, w, desc0.imagefmt,
						desc0.imagetype, buf);
			free(buf);
		} else {
			piglit_report_result(PIGLIT_FAIL);
			assert(!"create_solid_image() failed\n");
		}

		if (w > 1)
			w /= 2;
	}

#if 0  /* debug */
	printf("fmt0=%s, fmt1=%s, strgfmt0=%s, gettype0=%s\n",
		   piglit_get_gl_enum_name(desc0.internalfmt),
		   piglit_get_gl_enum_name(desc1.internalfmt),
		   piglit_get_gl_enum_name(desc0.storagefmt),
		   piglit_get_gl_enum_name(desc0.gettype));
	printf("bytes=%d, width=%d, viewTex[0]=%d, [1]=%d, [2]=%d\n",bytes,
		   width, viewTex[0], viewTex[1], viewTex[2]);
#endif

	glDeleteTextures(1, &tex);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	/* compare view0 all level texels bytes to view1 texels bytes */
	buffer0 = malloc(width * bytes);
	buffer1 = malloc(width * bytes);
	w = width;
	for (l = 0; l < levels; l++) {
		glBindTexture(GL_TEXTURE_1D, viewTex[0]);
		glGetTexImage(GL_TEXTURE_1D, l, desc0.getfmt, desc0.gettype,
			      buffer0);

		glBindTexture(GL_TEXTURE_1D, viewTex[1]);
		glGetTexImage(GL_TEXTURE_1D, l, desc1.getfmt, desc1.gettype,
			      buffer1);
		if (buffers_equal(buffer0, buffer1, w)) {
			pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
			printf("level %d texel mismatch view0 and view1, width=%d\n",
			       l, w);
			printf("internal format0 %s, internal format1 %s\n",
			       piglit_get_gl_enum_name(desc0.internalfmt),
			       piglit_get_gl_enum_name(desc1.internalfmt));
			pass = false;
		}

		if (w > 1)
			w /= 2;
	}

	/* compare view1 base level texels to view2 after view0 and view1
	   deleted */
	glBindTexture(GL_TEXTURE_1D, viewTex[1]);
	glGetTexImage(GL_TEXTURE_1D, 0, desc1.getfmt, desc1.gettype, buffer1);

	glTextureView(viewTex[2], GL_TEXTURE_1D, viewTex[0],
		      desc0.internalfmt, 0, 1, 0, 1);
	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
	glDeleteTextures(2, viewTex);
	glBindTexture(GL_TEXTURE_1D, viewTex[2]);
	glGetTexImage(GL_TEXTURE_1D, 0, desc0.getfmt, desc0.gettype, buffer0);

	if (buffers_equal(buffer0, buffer1, width)) {
		pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
		printf("Mismatched texels view1 and view2\n");
		printf("internal format0 %s, internal format1 %s\n",
			       piglit_get_gl_enum_name(desc0.internalfmt),
			       piglit_get_gl_enum_name(desc1.internalfmt));
		pass = false;
	}

	free(buffer0);
	free(buffer1);
	glDeleteTextures(1, &viewTex[2]);

	return pass;
}
Example #12
0
/**
 * Do error-check tests for texture targets
 */
static bool
test_target_errors(GLenum target)
{
	GLint width = 64, height = 14, depth = 8;
	const GLsizei levels = 1;
	GLuint tex;
	enum piglit_result pass = true;
	GLenum legalTargets[4];
	unsigned int numTargets, numIllegalTargets;
	GLenum illegalTargets[] = {
		GL_TEXTURE_1D,
		GL_TEXTURE_2D,
		GL_TEXTURE_3D,
		GL_TEXTURE_CUBE_MAP,
		GL_TEXTURE_RECTANGLE,
		GL_TEXTURE_1D_ARRAY,
		GL_TEXTURE_2D_ARRAY,
		GL_TEXTURE_CUBE_MAP_ARRAY,
		GL_TEXTURE_2D_MULTISAMPLE,
		GL_TEXTURE_2D_MULTISAMPLE_ARRAY
	};
	GLsizei texSamples;

	if (piglit_is_extension_supported("GL_ARB_texture_storage_multisample")) {
		numIllegalTargets = ARRAY_SIZE(illegalTargets);
		glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &texSamples);
	} else {
		numIllegalTargets =  ARRAY_SIZE(illegalTargets) -2;
		texSamples = 1;
	}

	glGenTextures(1, &tex);   /* orig tex */
	glBindTexture(target, tex);

	switch (target) {
	case GL_TEXTURE_1D:
		glTexStorage1D(target, levels, GL_RGBA8, width);
		numTargets = update_valid_arrays(legalTargets, illegalTargets,
				    numIllegalTargets,
				    GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, 0);
		break;
	case GL_TEXTURE_1D_ARRAY:
		glTexStorage2D(target, levels, GL_RGBA8, width, height);
		numTargets = update_valid_arrays(legalTargets, illegalTargets,
				    numIllegalTargets,
				    GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, 0);
		break;
	case GL_TEXTURE_2D:
		glTexStorage2D(target, levels, GL_RGBA8, width, height);
		numTargets = update_valid_arrays(legalTargets, illegalTargets,
				    numIllegalTargets,
				    GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, 0);
		break;
	case  GL_TEXTURE_RECTANGLE:
		glTexStorage2D(target, levels, GL_RGBA8, width, height);
		numTargets = update_valid_arrays(legalTargets, illegalTargets,
				    numIllegalTargets,
				    GL_TEXTURE_RECTANGLE, 0);
		break;
	case GL_TEXTURE_CUBE_MAP:
		width = height;
		glTexStorage2D(target, levels, GL_RGBA8, width, height);
		numTargets = update_valid_arrays(legalTargets, illegalTargets,
				    numIllegalTargets,
				    GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D,
				    GL_TEXTURE_2D_ARRAY,
				    GL_TEXTURE_CUBE_MAP_ARRAY, 0);
		break;
	case GL_TEXTURE_3D:
		glTexStorage3D(target, levels, GL_RGBA8, width, height, depth);
		numTargets = update_valid_arrays(legalTargets, illegalTargets,
				    numIllegalTargets,
				    GL_TEXTURE_3D, 0);
		break;
	case GL_TEXTURE_CUBE_MAP_ARRAY:
	case GL_TEXTURE_2D_ARRAY:
		height = width;
		glTexStorage3D(target, levels, GL_RGBA8, width, height, depth*6);
		numTargets = update_valid_arrays(legalTargets, illegalTargets,
				    numIllegalTargets,
				    GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D,
				    GL_TEXTURE_2D_ARRAY,
				    GL_TEXTURE_CUBE_MAP_ARRAY, 0);
		break;
	case GL_TEXTURE_2D_MULTISAMPLE:
		glTexStorage2DMultisample(target, texSamples, GL_RGBA8,
					  width, height, GL_TRUE);
		numTargets = update_valid_arrays(legalTargets, illegalTargets,
				    numIllegalTargets,
				    GL_TEXTURE_2D_MULTISAMPLE,
				    GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
		break;
	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
		glTexStorage3DMultisample(target, texSamples, GL_RGBA8,
					  width, height, depth, GL_TRUE);
		numTargets = update_valid_arrays(legalTargets, illegalTargets,
				    numIllegalTargets,
				    GL_TEXTURE_2D_MULTISAMPLE,
				    GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 0);
		break;
	default:
		assert(0);
		numTargets = 0;
		break;
	}

	if (!piglit_check_gl_error(GL_NO_ERROR)) {
		printf("%s Found gl errors prior to testing glTextureView\n",
				   TestName);
		pass = false;
		goto err_out;
	}

	/* ensure TextureView of legal targets  works without gl errors */
	pass = pass && check_target_array(GL_NO_ERROR, numTargets, legalTargets,
					  GL_RG16, tex, levels);
	/* ensure TextureView  of illegal targets returns an error */
	pass = pass && check_target_array(GL_INVALID_OPERATION,
					  numIllegalTargets,
					  illegalTargets,
					  GL_RG16, tex, levels);
err_out:
	glDeleteTextures(1, &tex);

	return pass;
}
Example #13
0
    // Creation / loading methods
    void GL3PlusTexture::createInternalResourcesImpl(void)
    {
        // set HardwareBuffer::Usage for TU_RENDERTARGET if nothing else specified
        if((mUsage & TU_RENDERTARGET) && (mUsage & ~TU_RENDERTARGET) == 0)
            mUsage |= HardwareBuffer::HBU_DYNAMIC;

        // Adjust format if required.
        mFormat = TextureManager::getSingleton().getNativeFormat(mTextureType, mFormat, mUsage);

        // Check requested number of mipmaps.
        uint32 maxMips = getMaxMipmaps();

        if (PixelUtil::isCompressed(mFormat) && (mNumMipmaps == 0))
            mNumRequestedMipmaps = 0;

        mNumMipmaps = mNumRequestedMipmaps;
        if (mNumMipmaps > maxMips)
            mNumMipmaps = maxMips;

        // Create a texture object and identify its GL type.
        OGRE_CHECK_GL_ERROR(glGenTextures(1, &mTextureID));
        GLenum texTarget = getGL3PlusTextureTarget();

        // Calculate size for all mip levels of the texture.
        uint32 width, height, depth;

        if ((mWidth * PixelUtil::getNumElemBytes(mFormat)) & 3) {
            // Standard alignment of 4 is not right for some formats.
            OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
        }

        // Bind texture object to its type, making it the active texture object
        // for that type.
        mRenderSystem->_getStateCacheManager()->bindGLTexture( texTarget, mTextureID );

        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_BASE_LEVEL, 0);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_MAX_LEVEL, mNumMipmaps);

        // Set some misc default parameters, these can of course be changed later.
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget,
                                            GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget,
                                            GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget,
                                            GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget,
                                            GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

        // Set up texture swizzling.
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
        mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
	
        if (PixelUtil::isLuminance(mFormat) && (mRenderSystem->hasMinGLVersion(3, 3) || mRenderSystem->checkExtension("GL_ARB_texture_swizzle")))
        {
            if (PixelUtil::getComponentCount(mFormat) == 2)
            {
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
            }
            else
            {
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_R, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_G, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_B, GL_RED);
                mRenderSystem->_getStateCacheManager()->setTexParameteri(texTarget, GL_TEXTURE_SWIZZLE_A, GL_ONE);
            }
        }

        GLenum format = GL3PlusPixelUtil::getGLInternalFormat(mFormat, mHwGamma);
        GLenum datatype = GL3PlusPixelUtil::getGLOriginDataType(mFormat);
        width = mWidth;
        height = mHeight;
        depth = mDepth;

        // Allocate texture storage so that glTexSubImageXD can be
        // used to upload the texture.
        if (PixelUtil::isCompressed(mFormat))
        {
            // Compressed formats
            GLsizei size;

            for (uint32 mip = 0; mip <= mNumMipmaps; mip++)
            {
                size = static_cast<GLsizei>(PixelUtil::getMemorySize(width, height, depth, mFormat));
                // std::stringstream str;
                // str << "GL3PlusTexture::create - " << StringConverter::toString(mTextureID)
                // << " bytes: " << StringConverter::toString(PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat))
                // << " Mip: " + StringConverter::toString(mip)
                // << " Width: " << StringConverter::toString(width)
                // << " Height: " << StringConverter::toString(height)
                // << " Format " << PixelUtil::getFormatName(mFormat)
                // << " Internal Format: 0x" << std::hex << format
                // << " Origin Format: 0x" << std::hex << GL3PlusPixelUtil::getGLOriginFormat(mFormat)
                // << " Data type: 0x" << std::hex << datatype;
                // LogManager::getSingleton().logMessage(LML_NORMAL, str.str());

                switch(mTextureType)
                {
                case TEX_TYPE_1D:
                    OGRE_CHECK_GL_ERROR(glCompressedTexImage1D(GL_TEXTURE_1D, mip, format,
                                                               width, 0,
                                                               size, NULL));
                    break;
                case TEX_TYPE_2D:
                    OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_2D,
                                                               mip,
                                                               format,
                                                               width, height,
                                                               0,
                                                               size,
                                                               NULL));
                    break;
                case TEX_TYPE_2D_RECT:
                    OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_RECTANGLE,
                                                               mip,
                                                               format,
                                                               width, height,
                                                               0,
                                                               size,
                                                               NULL));
                    break;
                case TEX_TYPE_2D_ARRAY:
                case TEX_TYPE_3D:
                    OGRE_CHECK_GL_ERROR(glCompressedTexImage3D(texTarget, mip, format,
                                                               width, height, depth, 0,
                                                               size, NULL));
                    break;
                case TEX_TYPE_CUBE_MAP:
                    for(int face = 0; face < 6; face++) {
                        OGRE_CHECK_GL_ERROR(glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
                                                                   width, height, 0,
                                                                   size, NULL));
                    }
                    break;
                default:
                    break;
                };

                if (width > 1)
                {
                    width = width / 2;
                }
                if (height > 1)
                {
                    height = height / 2;
                }
                if (depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY)
                {
                    depth = depth / 2;
                }
            }
        }
        else
        {
            if (mRenderSystem->hasMinGLVersion(4, 2) || mRenderSystem->checkExtension("GL_ARB_texture_storage"))
            {
                switch(mTextureType)
                {
                case TEX_TYPE_1D:
                    OGRE_CHECK_GL_ERROR(glTexStorage1D(GL_TEXTURE_1D, GLsizei(mNumMipmaps+1), format, GLsizei(width)));
                    break;
                case TEX_TYPE_2D:
                case TEX_TYPE_2D_RECT:
                    OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_2D, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height)));
                    break;
                case TEX_TYPE_CUBE_MAP:
                    OGRE_CHECK_GL_ERROR(glTexStorage2D(GL_TEXTURE_CUBE_MAP, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height)));
                    break;
                case TEX_TYPE_2D_ARRAY:
                    OGRE_CHECK_GL_ERROR(glTexStorage3D(GL_TEXTURE_2D_ARRAY, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height), GLsizei(depth)));
                    break;
                case TEX_TYPE_3D:
                    OGRE_CHECK_GL_ERROR(glTexStorage3D(GL_TEXTURE_3D, GLsizei(mNumMipmaps+1), format, GLsizei(width), GLsizei(height), GLsizei(depth)));
                    break;
                }
            }
            else
            {
                GLenum originFormat = GL3PlusPixelUtil::getGLOriginFormat(mFormat);

                // Run through this process to pregenerate mipmap pyramid
                for(uint32 mip = 0; mip <= mNumMipmaps; mip++)
                {
                    //                    std::stringstream str;
                    //                    str << "GL3PlusTexture::create - " << StringConverter::toString(mTextureID)
                    //                    << " bytes: " << StringConverter::toString(PixelUtil::getMemorySize(width, height, depth, mFormat))
                    //                    << " Mip: " + StringConverter::toString(mip)
                    //                    << " Width: " << StringConverter::toString(width)
                    //                    << " Height: " << StringConverter::toString(height)
                    //                    << " Format " << PixelUtil::getFormatName(mFormat)
                    //                    << " Internal Format: 0x" << std::hex << format
                    //                    << " Origin Format: 0x" << std::hex << GL3PlusPixelUtil::getGLOriginFormat(mFormat)
                    //                    << " Data type: 0x" << std::hex << datatype;
                    //                    LogManager::getSingleton().logMessage(LML_NORMAL, str.str());

                    // Normal formats
                    switch(mTextureType)
                    {
                    case TEX_TYPE_1D:
                        OGRE_CHECK_GL_ERROR(glTexImage1D(GL_TEXTURE_1D, mip, format,
                                                         width, 0,
                                                         originFormat, datatype, NULL));
                        break;
                    case TEX_TYPE_2D:
                        OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_2D,
                                                         mip,
                                                         format,
                                                         width, height,
                                                         0,
                                                         originFormat,
                                                         datatype, NULL));
                        break;
                    case TEX_TYPE_2D_RECT:
                        OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_RECTANGLE,
                                                         mip,
                                                         format,
                                                         width, height,
                                                         0,
                                                         originFormat,
                                                         datatype, NULL));
                        break;
                    case TEX_TYPE_3D:
                    case TEX_TYPE_2D_ARRAY:
                        OGRE_CHECK_GL_ERROR(glTexImage3D(texTarget, mip, format,
                                                         width, height, depth, 0,
                                                         originFormat, datatype, NULL));
                        break;
                    case TEX_TYPE_CUBE_MAP:
                        for(int face = 0; face < 6; face++) {
                            OGRE_CHECK_GL_ERROR(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, mip, format,
                                                             width, height, 0,
                                                             originFormat, datatype, NULL));
                        }
                        break;
                    default:
                        break;
                    };

                    if (width > 1)
                    {
                        width = width / 2;
                    }
                    if (height > 1)
                    {
                        height = height / 2;
                    }
                    if (depth > 1 && mTextureType != TEX_TYPE_2D_ARRAY)
                    {
                        depth = depth / 2;
                    }
                }
            }
        }

        // Reset unpack alignment to defaults
        OGRE_CHECK_GL_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 4));

        _createSurfaceList();

        // Generate mipmaps after all texture levels have been loaded
        // This is required for compressed formats such as DXT
        if (PixelUtil::isCompressed(mFormat) && mUsage & TU_AUTOMIPMAP)
        {
            OGRE_CHECK_GL_ERROR(glGenerateMipmap(getGL3PlusTextureTarget()));
        }

        // Get final internal format.
        mFormat = getBuffer(0,0)->getFormat();
    }
Example #14
0
////////////////////////////////////////////////////////////////////////////////
// on init cb
void on_init()
{
	// variables
	GLuint texture=0;
	GLint iterationCnt=sizeof(internalFormats)/(sizeof(GLenum));

#ifndef _WIN32
	// Configure debug output
	glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
	glDebugMessageCallbackARB(
			reinterpret_cast<GLDEBUGPROCARB>(&gl_debug_message_callback),
			reinterpret_cast<GLvoid*>(&i) );
#endif

	for(i=0; i<iterationCnt; ++i)
	{
		glGenTextures(1, &texture);
		glBindTexture(GL_TEXTURE_1D, texture);
			glTexStorage1D(GL_TEXTURE_1D,
			               1,
			               internalFormats[i],
			               1);
		glBindTexture(GL_TEXTURE_1D, 0);
		glDeleteTextures(1, &texture);
#ifdef _WIN32
		GLenum error = glGetError();
		if(error!=GL_NO_ERROR)
			std::cerr << "glTexStorage1D gave "
			          << gl_error_to_string(error)
			          << " (internalformat= "
			          << internalFormatsStr[i]
		              << ")\n";
#endif
	}
	std::cerr << '\n';

	// 2D tests
	for(i=0; i<iterationCnt; ++i)
	{
		glGenTextures(1, &texture);
		glBindTexture(GL_TEXTURE_2D, texture);
			glTexStorage2D(GL_TEXTURE_2D,
			               1,
			               internalFormats[i],
			               1,
			               1);
		glDeleteTextures(1, &texture);
#ifdef _WIN32
		GLenum error = glGetError();
		if(error!=GL_NO_ERROR)
			std::cerr << "glTexStorage2D gave "
			          << gl_error_to_string(error)
			          << " (internalformat= "
			          << internalFormatsStr[i]
		              << ")\n";
#endif
	}
	std::cerr << '\n';

	// 3D tests
	for(i=0; i<iterationCnt; ++i)
	{

		glGenTextures(1, &texture);
		glBindTexture(GL_TEXTURE_3D, texture);
			glTexStorage3D(GL_TEXTURE_3D,
			               1,
			               internalFormats[i],
			               1,
			               1,
			               1);
		glDeleteTextures(1, &texture);
#ifdef _WIN32
		GLenum error = glGetError();
		if(error!=GL_NO_ERROR)
			std::cerr << "glTexStorage3D gave "
			          << gl_error_to_string(error)
			          << " (internalformat= "
			          << internalFormatsStr[i]
		              << ")\n";
#endif
	}
}
Example #15
0
	void OGLTexture1D::CreateHWResource(ArrayRef<ElementInitData> init_data, float4 const * clear_value_hint)
	{
		KFL_UNUSED(clear_value_hint);

		GLint glinternalFormat;
		GLenum glformat;
		GLenum gltype;
		OGLMapping::MappingFormat(glinternalFormat, glformat, gltype, format_);

		if (sample_count_ <= 1)
		{
			uint32_t const pbo_size = mipmap_start_offset_.back() * array_size_;
			if (glloader_GL_VERSION_4_5() || glloader_GL_ARB_direct_state_access())
			{
				glTextureParameteri(texture_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1);

				glNamedBufferStorage(pbo_, pbo_size, nullptr, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT | GL_DYNAMIC_STORAGE_BIT);

				uint32_t const w0 = this->Width(0);

				if (array_size_ > 1)
				{
					glTextureStorage2D(texture_, num_mip_maps_, glinternalFormat, w0, array_size_);
				}
				else
				{
					glTextureStorage1D(texture_, num_mip_maps_, glinternalFormat, w0);
				}

				if (!init_data.empty())
				{
					for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
					{
						for (uint32_t level = 0; level < num_mip_maps_; ++ level)
						{
							uint32_t const w = this->Width(level);
							GLvoid const * data = init_data[array_index * num_mip_maps_ + level].data;

							if (IsCompressedFormat(format_))
							{
								uint32_t const block_size = NumFormatBytes(format_) * 4;
								GLsizei const image_size = ((w + 3) / 4) * block_size;

								if (array_size_ > 1)
								{
									glCompressedTextureSubImage2D(texture_, level, 0, array_index,
										w, 1, glformat, image_size, data);
								}
								else
								{
									glCompressedTextureSubImage1D(texture_, level, 0,
										w, glformat, image_size, data);
								}
							}
							else
							{
								if (array_size_ > 1)
								{
									glTextureSubImage2D(texture_, level, 0, array_index, w, 1,
										glformat, gltype, data);
								}
								else
								{
									glTextureSubImage1D(texture_, level, 0, w, glformat, gltype, data);
								}
							}
						}
					}
				}
			}
			else
			{
				auto& re = *checked_cast<OGLRenderEngine*>(&Context::Instance().RenderFactoryInstance().RenderEngineInstance());
				
				re.BindTexture(0, target_type_, texture_);
				glTexParameteri(target_type_, GL_TEXTURE_MAX_LEVEL, num_mip_maps_ - 1);

				re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_);
				if (glloader_GL_VERSION_4_4() || glloader_GL_ARB_buffer_storage())
				{
					glBufferStorage(GL_PIXEL_UNPACK_BUFFER, pbo_size, nullptr, GL_DYNAMIC_STORAGE_BIT);
				}
				else
				{
					glBufferData(GL_PIXEL_UNPACK_BUFFER, pbo_size, nullptr, GL_STREAM_COPY);
				}
				re.BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

				if (glloader_GL_VERSION_4_2() || glloader_GL_ARB_texture_storage())
				{
					uint32_t const w0 = this->Width(0);

					if (array_size_ > 1)
					{
						glTexStorage2D(target_type_, num_mip_maps_, glinternalFormat, w0, array_size_);
					}
					else
					{
						glTexStorage1D(target_type_, num_mip_maps_, glinternalFormat, w0);
					}

					if (!init_data.empty())
					{
						for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
						{
							for (uint32_t level = 0; level < num_mip_maps_; ++ level)
							{
								uint32_t const w = this->Width(level);
								GLvoid const * data = init_data[array_index * num_mip_maps_ + level].data;

								if (IsCompressedFormat(format_))
								{
									uint32_t const block_size = NumFormatBytes(format_) * 4;
									GLsizei const image_size = ((w + 3) / 4) * block_size;

									if (array_size_ > 1)
									{
										glCompressedTexSubImage2D(target_type_, level, 0, array_index,
											w, 1, glformat, image_size, data);
									}
									else
									{
										glCompressedTexSubImage1D(target_type_, level, 0,
											w, glformat, image_size, data);
									}
								}
								else
								{
									if (array_size_ > 1)
									{
										glTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, gltype, data);
									}
									else
									{
										glTexSubImage1D(target_type_, level, 0, w, glformat, gltype, data);
									}
								}
							}
						}
					}
				}
				else
				{
					for (uint32_t array_index = 0; array_index < array_size_; ++ array_index)
					{
						for (uint32_t level = 0; level < num_mip_maps_; ++ level)
						{
							uint32_t const w = this->Width(level);

							if (IsCompressedFormat(format_))
							{
								uint32_t const block_size = NumFormatBytes(format_) * 4;
								GLsizei const image_size = ((w + 3) / 4) * block_size;

								if (array_size_ > 1)
								{
									if (0 == array_index)
									{
										glCompressedTexImage2D(target_type_, level, glinternalFormat,
											w, array_size_, 0, image_size * array_size_, nullptr);
									}

									if (!init_data.empty())
									{
										glCompressedTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, image_size, init_data[array_index * num_mip_maps_ + level].data);
									}
								}
								else
								{
									glCompressedTexImage1D(target_type_, level, glinternalFormat,
										w, 0, image_size,
										init_data.empty() ? nullptr : init_data[array_index * num_mip_maps_ + level].data);
								}
							}
							else
							{
								if (array_size_ > 1)
								{
									if (0 == array_index)
									{
										glTexImage2D(target_type_, level, glinternalFormat, w, array_size_, 0, glformat, gltype, nullptr);
									}

									if (!init_data.empty())
									{
										glTexSubImage2D(target_type_, level, 0, array_index, w, 1,
											glformat, gltype, init_data[array_index * num_mip_maps_ + level].data);
									}
								}
								else
								{
									glTexImage1D(target_type_, level, glinternalFormat, w, 0, glformat, gltype,
										init_data.empty() ? nullptr : init_data[array_index * num_mip_maps_ + level].data);
								}
							}
						}
					}
				}
			}
		}
		else
		{
			glBindRenderbuffer(GL_RENDERBUFFER, texture_);
			glRenderbufferStorageMultisample(GL_RENDERBUFFER, sample_count_, glinternalFormat, width_, 1);
		}

		hw_res_ready_ = true;
	}
Example #16
0
unsigned int loadKTX(const char * filename, unsigned int tex)
{
	FILE * fp;
	GLuint temp = 0;
	GLuint retval = 0;
	header h;
	size_t data_start, data_end;
	unsigned char * data;
	GLenum target = GL_NONE;

	fp = fopen(filename, "rb");

	if (!fp)
		return 0;

	if (fread(&h, sizeof(h), 1, fp) != 1)
		goto fail_read;

	if (memcmp(h.identifier, identifier, sizeof(identifier)) != 0)
		goto fail_header;

	if (h.endianness == 0x04030201)
	{
		// No swap needed
	}
	else if (h.endianness == 0x01020304)
	{
		// Swap needed
		h.endianness            = swap32(h.endianness);
		h.gltype                = swap32(h.gltype);
		h.gltypesize            = swap32(h.gltypesize);
		h.glformat              = swap32(h.glformat);
		h.glinternalformat      = swap32(h.glinternalformat);
		h.glbaseinternalformat  = swap32(h.glbaseinternalformat);
		h.pixelwidth            = swap32(h.pixelwidth);
		h.pixelheight           = swap32(h.pixelheight);
		h.pixeldepth            = swap32(h.pixeldepth);
		h.arrayelements         = swap32(h.arrayelements);
		h.faces                 = swap32(h.faces);
		h.miplevels             = swap32(h.miplevels);
		h.keypairbytes          = swap32(h.keypairbytes);
	}
	else
	{
		goto fail_header;
	}

	// Guess target (texture type)
	if (h.pixelheight == 0)
	{
		if (h.arrayelements == 0)
		{
			target = GL_TEXTURE_1D;
		}
		else
		{
			target = GL_TEXTURE_1D_ARRAY;
		}
	}
	else if (h.pixeldepth == 0)
	{
		if (h.arrayelements == 0)
		{
			if (h.faces == 0)
			{
				target = GL_TEXTURE_2D;
			}
			else
			{
				target = GL_TEXTURE_CUBE_MAP;
			}
		}
		else
		{
			if (h.faces == 0)
			{
				target = GL_TEXTURE_2D_ARRAY;
			}
			else
			{
				target = GL_TEXTURE_CUBE_MAP_ARRAY;
			}
		}
	}
	else
	{
		target = GL_TEXTURE_3D;
	}

	// Check for insanity...
	if (target == GL_NONE ||                                    // Couldn't figure out target
		(h.pixelwidth == 0) ||                                  // Texture has no width???
		(h.pixelheight == 0 && h.pixeldepth != 0))              // Texture has depth but no height???
	{
		goto fail_header;
	}

	temp = tex;
	if (tex == 0)
	{
		glGenTextures(1, &tex);
	}

	glBindTexture(target, tex);

	data_start = ftell(fp) + h.keypairbytes;
	fseek(fp, 0, SEEK_END);
	data_end = ftell(fp);
	fseek(fp, data_start, SEEK_SET);

	data = new unsigned char [data_end - data_start];
	memset(data, 0, data_end - data_start);

	fread(data, 1, data_end - data_start, fp);

	if (h.miplevels == 0)
	{
		h.miplevels = 1;
	}

	switch (target)
	{
	case GL_TEXTURE_1D:
		glTexStorage1D(GL_TEXTURE_1D, h.miplevels, h.glinternalformat, h.pixelwidth);
		glTexSubImage1D(GL_TEXTURE_1D, 0, 0, h.pixelwidth, h.glformat, h.glinternalformat, data);
		break;
	case GL_TEXTURE_2D:
		glTexStorage2D(GL_TEXTURE_2D, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight);
		{
			unsigned char * ptr = data;
			unsigned int height = h.pixelheight;
			unsigned int width = h.pixelwidth;
			glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
			for (unsigned int i = 0; i < h.miplevels; i++)
			{
				glTexSubImage2D(GL_TEXTURE_2D, i, 0, 0, width, height, h.glformat, h.gltype, ptr);
				ptr += height * calculate_stride(h, width, 1);
				height >>= 1;
				width >>= 1;
				if (!height)
					height = 1;
				if (!width)
					width = 1;
			}
		}
		break;
	case GL_TEXTURE_3D:
		glTexStorage3D(GL_TEXTURE_3D, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight, h.pixeldepth);
		glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.pixeldepth, h.glformat, h.gltype, data);
		break;
	case GL_TEXTURE_1D_ARRAY:
		glTexStorage2D(GL_TEXTURE_1D_ARRAY, h.miplevels, h.glinternalformat, h.pixelwidth, h.arrayelements);
		glTexSubImage2D(GL_TEXTURE_1D_ARRAY, 0, 0, 0, h.pixelwidth, h.arrayelements, h.glformat, h.gltype, data);
		break;
	case GL_TEXTURE_2D_ARRAY:
		glTexStorage3D(GL_TEXTURE_2D_ARRAY, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight, h.arrayelements);
		glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.arrayelements, h.glformat, h.gltype, data);
		break;
	case GL_TEXTURE_CUBE_MAP:
		glTexStorage2D(GL_TEXTURE_CUBE_MAP, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight);
		// glTexSubImage3D(GL_TEXTURE_CUBE_MAP, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.faces, h.glformat, h.gltype, data);
		{
			unsigned int face_size = calculate_face_size(h);
			for (unsigned int i = 0; i < h.faces; i++)
			{
				glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, h.pixelwidth, h.pixelheight, h.glformat, h.gltype, data + face_size * i);
			}
		}
		break;
	case GL_TEXTURE_CUBE_MAP_ARRAY:
		glTexStorage3D(GL_TEXTURE_CUBE_MAP_ARRAY, h.miplevels, h.glinternalformat, h.pixelwidth, h.pixelheight, h.arrayelements);
		glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, 0, 0, h.pixelwidth, h.pixelheight, h.faces * h.arrayelements, h.glformat, h.gltype, data);
		break;
	default:                                               // Should never happen
		goto fail_target;
	}

	if (h.miplevels == 1)
	{
		glGenerateMipmap(target);
	}

	retval = tex;

fail_target:
	delete [] data;

fail_header:;
fail_read:;
	fclose(fp);

	return retval;
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL42_nglTexStorage1D(JNIEnv *env, jclass clazz, jint target, jint levels, jint internalformat, jint width, jlong function_pointer) {
	glTexStorage1DPROC glTexStorage1D = (glTexStorage1DPROC)((intptr_t)function_pointer);
	glTexStorage1D(target, levels, internalformat, width);
}
Example #18
0
DDSTexture::DDSTexture(string filename) {
	filename = FOLDER + filename;
	gli::texture texture = gli::load(filename);
	if (texture.empty())
		return;

	gli::gl GL;
	gli::gl::format const Format = GL.translate(texture.format());
	this->target = GL.translate(texture.target());
	glGenTextures(1, &glId);
	glBindTexture(target, glId);
	glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0);
	glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, static_cast<GLint>(texture.levels() - 1));
	glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, Format.Swizzle[0]);
	glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, Format.Swizzle[1]);
	glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, Format.Swizzle[2]);
	glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, Format.Swizzle[3]);
	glm::tvec3<GLsizei> const Dimensions(texture.dimensions());
	GLsizei const FaceTotal = static_cast<GLsizei>(texture.layers() * texture.faces());
	switch (texture.target())
	{
	case gli::TARGET_1D:
		glTexStorage1D(target, static_cast<GLint>(texture.levels()), Format.Internal, Dimensions.x);
		break;
	case gli::TARGET_1D_ARRAY:
	case gli::TARGET_2D:
	case gli::TARGET_CUBE:
		glTexStorage2D(
			target, static_cast<GLint>(texture.levels()), Format.Internal,
			Dimensions.x, texture.target() == gli::TARGET_2D ? Dimensions.y : FaceTotal);
		break;
	case gli::TARGET_2D_ARRAY:
	case gli::TARGET_3D:
	case gli::TARGET_CUBE_ARRAY:
		glTexStorage3D(
			target, static_cast<GLint>(texture.levels()), Format.Internal,
			Dimensions.x, Dimensions.y, texture.target() == gli::TARGET_3D ? Dimensions.z : FaceTotal);
		break;
	default: assert(0); break;
	}
	for (std::size_t Layer = 0; Layer < texture.layers(); ++Layer) {
		for (std::size_t Face = 0; Face < texture.faces(); ++Face) {
			for (std::size_t Level = 0; Level < texture.levels(); ++Level)
			{
				GLsizei const LayerGL = static_cast<GLsizei>(Layer);
				glm::tvec3<GLsizei> Dimensions(texture.dimensions(Level));
				if (gli::is_target_cube(texture.target()))
					target = static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + Face);
				switch (texture.target())
				{
				case gli::TARGET_1D:
					if (gli::is_compressed(texture.format()))
						glCompressedTexSubImage1D(
							target, static_cast<GLint>(Level), 0, Dimensions.x,
							Format.Internal, static_cast<GLsizei>(texture.size(Level)),
							texture.data(Layer, Face, Level));
					else
						glTexSubImage1D(
							target, static_cast<GLint>(Level), 0, Dimensions.x, Format.External, Format.Type,
							texture.data(Layer, Face, Level));
					break;
				case gli::TARGET_1D_ARRAY:
				case gli::TARGET_2D:
				case gli::TARGET_CUBE:
					if (gli::is_compressed(texture.format()))
						glCompressedTexSubImage2D(
							target, static_cast<GLint>(Level), 0, 0,
							Dimensions.x, texture.target() == gli::TARGET_1D_ARRAY ? 0 : Dimensions.y,
							Format.Internal, static_cast<GLsizei>(texture.size(Level)),
							texture.data(Layer, Face, Level));
					else
						glTexSubImage2D(
							target, static_cast<GLint>(Level), 0, 0,
							Dimensions.x, texture.target() == gli::TARGET_1D_ARRAY ? LayerGL : Dimensions.y,
							Format.External, Format.Type, texture.data(Layer, Face, Level));
					break;
				case gli::TARGET_2D_ARRAY:
				case gli::TARGET_3D:
				case gli::TARGET_CUBE_ARRAY:
					if (gli::is_compressed(texture.format()))
						glCompressedTexSubImage3D(
							target, static_cast<GLint>(Level), 0, 0, 0,
							Dimensions.x, Dimensions.y, texture.target() == gli::TARGET_3D ? Dimensions.z : LayerGL,
							Format.Internal, static_cast<GLsizei>(texture.size(Level)),
							texture.data(Layer, Face, Level));
					else
						glTexSubImage3D(
							target, static_cast<GLint>(Level), 0, 0, 0,
							Dimensions.x, Dimensions.y, texture.target() == gli::TARGET_3D ? Dimensions.z : LayerGL,
							Format.External, Format.Type, texture.data(Layer, Face, Level));
					break;
				default: assert(0); break;
				}
			}
		}
	}

	glGenerateMipmap(target);

	glBindTexture(target, 0);
}
Example #19
0
inline void tex_storage_1d(TextureTarget target, int32_t levels, uint32_t format, uint32_t width)
{
	ARC_GL_CLEAR_ERRORS();
	glTexStorage1D((GLenum)target, levels, (GLenum)format, width);
	ARC_GL_CHECK_FOR_ERRORS();
}
Example #20
0
/**
 * Simple views  of textures; test rendering with various texture view targets
 */
static bool
test_render_with_targets(GLenum target)
{
	GLuint tex, newTex;
	GLint width = 128, height = 64, depth = 4, levels = 8;
	GLint l;
	bool pass = true;

	glUseProgram(0);
	glGenTextures(1, &tex);
	glBindTexture(target, tex);

	switch (target) {
	case GL_TEXTURE_1D:
		glTexStorage1D(target, levels, GL_RGBA8, width);
		height = 1;
		depth = 1;
		break;
	case GL_TEXTURE_2D:
		glTexStorage2D(target, levels, GL_RGBA8, width, height);
		depth = 1;
		break;
	case GL_TEXTURE_3D:
	case GL_TEXTURE_2D_ARRAY:
		glTexStorage3D(target, levels, GL_RGBA8, width, height, depth);
		break;
	default:
		/* only handle subset of legal targets */
		piglit_report_result(PIGLIT_FAIL);
		assert(!"Illegal target for test_render_with_targets()\n");
		break;
	}

	/* load each mipmap with a different color texture */
	for (l = 0; l < levels; l++) {
		GLubyte *buf = create_solid_image(width, height, depth, 4, l);

		if (buf != NULL) {
			switch(target) {
			case GL_TEXTURE_1D:
				glTexSubImage1D(GL_TEXTURE_1D, l, 0, width,
						GL_RGBA, GL_UNSIGNED_BYTE, buf);
				break;
			case GL_TEXTURE_2D:
				glTexSubImage2D(GL_TEXTURE_2D, l, 0, 0, width,
						height, GL_RGBA,
						GL_UNSIGNED_BYTE, buf);
				break;
			case GL_TEXTURE_3D:
			case GL_TEXTURE_2D_ARRAY:
				glTexSubImage3D(target, l, 0, 0, 0, width,
						height, depth, GL_RGBA,
						GL_UNSIGNED_BYTE, buf);
				break;
			}
			free(buf);
		} else {
			piglit_report_result(PIGLIT_FAIL);
			assert(!"create_solid_image() failed\n");
		}

		if (width > 1)
			width /= 2;
		if (height > 1)
			height /= 2;
		if (depth > 1 && target == GL_TEXTURE_3D)
			depth /= 2;
	}

	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
		printf("%s: Found gl errors prior to testing glTextureView\n",
				   TestName);
		glDeleteTextures(1, &tex);

		return false;
	}

	/* create view of texture and bind it to target */
	glGenTextures(1, &newTex);
	glTextureView(newTex, target, tex,  GL_RGBA8, 0, levels, 0, 1);
	glDeleteTextures(1, &tex);
	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(target, newTex);

	/* draw a quad/line using each texture mipmap level */
	glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
			GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	for (l = 0; l < levels; l++) {
		GLfloat expected[3];
		int p;

		glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, l);
		glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, l);

		glClear(GL_COLOR_BUFFER_BIT);

		switch (target) {
		case GL_TEXTURE_1D:
			glUseProgram(prog1D);
			glUniform1i(tex_loc_1D, 0);
			piglit_draw_rect_tex(-1.0, -1.0, 2.0, 2.0, 0.0, 0.0,
					     1.0, 1.0);
			break;
		case GL_TEXTURE_2D:
			glEnable(target);
			piglit_draw_rect_tex(-1.0, -1.0, 2.0, 2.0, 0.0, 0.0,
					     1.0, 1.0);
			glDisable(target);
			break;
		case GL_TEXTURE_2D_ARRAY:
			glUseProgram(prog2Darray);
			glUniform1i(tex_loc_2Darray, 0);
			draw_3d_depth(-1.0, -1.0, 2.0, 2.0, l);
			break;
		case GL_TEXTURE_3D:
			glEnable(target);
			draw_3d_depth(-1.0, -1.0, 2.0, 2.0, l);
			glDisable(target);
			break;
		}

		expected[0] = Colors[l][0] / 255.0;
		expected[1] = Colors[l][1] / 255.0;
		expected[2] = Colors[l][2] / 255.0;

		p = piglit_probe_pixel_rgb(piglit_width/2, piglit_height/2,
					   expected);

		piglit_present_results();

#if 0		/* debug */
		printf("for level=%d, target=%s, expected color=%f %f %f\n",
			   l, piglit_get_gl_enum_name(target), expected[0],
				   expected[1], expected[2]);
		sleep(1);
#endif

		if (!p) {
			printf("%s: wrong color for mipmap level %d\n",
			       TestName, l);
			pass = false;
		}
	}
	glDeleteTextures(1, &newTex);

	return pass;
}
Example #21
0
//---------------------------------------------------------------------------//
  void TextureGL4::create(const TextureCreationParams& clDeclaration, CreationMethod eCreationMethod /*= CreationMethod::UPLOADED_ONCE*/)
  {
    // TODO: Implement Cubemap- and array textures 
    destroy();

    TextureCreationParams* pBaseParams = &m_clParameters;
    *pBaseParams = clDeclaration;

    GLenum eGLformat, eGLinternalFormat, eGLpixelType;
    Adapter::mapGLpixelFormats(clDeclaration.eFormat, clDeclaration.bIsDepthStencil, 
      eGLformat, eGLinternalFormat, eGLpixelType);

    m_clParameters.eFormatGL = eGLformat;
    m_clParameters.eInternalFormatGL = eGLinternalFormat;
    m_clParameters.ePixelTypeGL = eGLpixelType;
    
    GLenum eTextureType = 0u;
    GLenum eTexBindingQuery = 0u;
    GLuint uNumDimensions = 0u;

    ASSERT(clDeclaration.u16Width > 0u, "Invalid texture dimensions");
    if (clDeclaration.u16Height == 0u && clDeclaration.u16Depth == 0u )
    {
      eTextureType = GL_TEXTURE_1D;
      eTexBindingQuery = GL_TEXTURE_BINDING_1D;
      uNumDimensions = 1u;
    } 
    else if (clDeclaration.u16Height > 0u && clDeclaration.u16Depth == 0u) 
    {
      eTextureType = GL_TEXTURE_2D;
      eTexBindingQuery = GL_TEXTURE_BINDING_2D;
      uNumDimensions = 2u;
    }
    else if (clDeclaration.u16Height > 0u && clDeclaration.u16Depth > 0u)
    {
      eTextureType = GL_TEXTURE_3D;
      eTexBindingQuery = GL_TEXTURE_BINDING_3D;
      uNumDimensions = 3u;
    }
    
    ASSERT (uNumDimensions > 0u, "Invalid texture dimensions");
    m_clParameters.eTextureTypeGL = eTextureType;
    m_clParameters.eTexBindQueryGL = eTexBindingQuery;

    m_clStateInfo.isArrayTexture = false; // TODO: Implement
    m_clStateInfo.isCubemap = false; // TODO: Implement
    m_clStateInfo.isLocked = false;
    m_clStateInfo.isSRGB = (eGLinternalFormat == GL_SRGB8_ALPHA8 || eGLinternalFormat == GL_SRGB8);
    m_clStateInfo.numDimensions = uNumDimensions;

    // Determine the max number of miplevels
    uint8 u8MipLevelsWidth  = clDeclaration.u16Width == 0u ? 0u : glm::log2(clDeclaration.u16Width);
    uint8 u8MipLevelsHeight = clDeclaration.u16Height == 0u ? 0u : glm::log2(clDeclaration.u16Height);
    uint8 u8MipLevelsDepth  = clDeclaration.u16Depth == 0u ? 0u : glm::log2(clDeclaration.u16Depth);

    uint8 u8MaxMipLevels = u8MipLevelsWidth;
    if (uNumDimensions > 1u) {
      u8MaxMipLevels = glm::min(u8MaxMipLevels, u8MipLevelsHeight);
    }
    if (uNumDimensions > 2u) {
      u8MaxMipLevels = glm::min(u8MaxMipLevels, u8MipLevelsDepth);
    }

    m_clParameters.u8NumMipLevels = 
      glm::min(glm::max(static_cast<uint8>(1u), m_clParameters.u8NumMipLevels), u8MaxMipLevels);
    
    // Internally store the raw texture data if required
    m_clStateInfo.cachesTextureData = false;
    if (m_clParameters.pPixelData != nullptr && eCreationMethod == CreationMethod::UPLOADED_OFTEN) {
      void* pDataCache = FANCY_ALLOCATE(m_clParameters.uPixelDataSizeBytes, MemoryCategory::TEXTURES);
      memcpy(pDataCache, m_clParameters.pPixelData, m_clParameters.uPixelDataSizeBytes);
      m_clParameters.pPixelData = pDataCache;
      m_clStateInfo.cachesTextureData = true;
    }

    // determine the currently bound texture
    GLint origBoundTexture;
    glGetIntegerv(eTexBindingQuery, &origBoundTexture);
  
    // construct the new texture
    glGenTextures(1u, &m_uGLhandle);
    glBindTexture(eTextureType, m_uGLhandle);
    
    if (uNumDimensions == 2u) {
      glTexStorage2D(eTextureType, m_clParameters.u8NumMipLevels, eGLinternalFormat, 
        m_clParameters.u16Width, m_clParameters.u16Height );
    }
    else if (uNumDimensions == 3u) {
      glTexStorage3D(eTextureType, m_clParameters.u8NumMipLevels, eGLinternalFormat, 
        m_clParameters.u16Width, m_clParameters.u16Height, m_clParameters.u16Depth );
    }
    else {
      glTexStorage1D(eTextureType, m_clParameters.u8NumMipLevels, eGLinternalFormat, 
        m_clParameters.u16Width );
    }

    if (m_clParameters.pPixelData != nullptr) {
      setPixelData(m_clParameters.pPixelData, m_clParameters.uPixelDataSizeBytes);
    }

    // restore originally bound texture
    glBindTexture(eTextureType, static_cast<GLuint>(origBoundTexture));
  }
PIGLIT_GL_TEST_CONFIG_END

enum piglit_result
piglit_display(void)
{
	GLuint tex[3];
	GLint level;
	GLint num_level;

	/* The GL ES 3.0 spec says:
	 *
	 *     "The [initial] value of TEXTURE_IMMUTABLE_LEVELS is 0."
	 */
	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	if (!piglit_check_gl_error(GL_NO_ERROR)) {
		piglit_report_result(PIGLIT_FAIL);
	}
	if (level != 0) {
		printf("Expected 0 levels initially, but glGetTexParameteriv "
		       "returned %d for GL_TEXTURE_1D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	}

	glGenTextures(5, tex);

	glBindTexture(GL_TEXTURE_1D, tex[0]);
	glTexStorage1D(GL_TEXTURE_1D, 3, GL_RGBA8, 32);
	glGetTexParameteriv(GL_TEXTURE_1D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	glGetTexParameteriv(GL_TEXTURE_1D, GL_TEXTURE_VIEW_NUM_LEVELS, &num_level);
	if (level != 3) {
		printf("Expected 3 levels, but glGetTexParameteriv returned "
		       "%d for GL_TEXTURE_1D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	} else if (level != num_level) {
		printf("Expected queries of TEXTURE_IMMUTABLE_LEVELS and "
		       "TEXTURE_VIEW_NUM_LEVELS to return identical results.");
		piglit_report_result(PIGLIT_FAIL);
	}

	glBindTexture(GL_TEXTURE_2D, tex[1]);
	glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 32, 32);
	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_VIEW_NUM_LEVELS, &num_level);
	if (level != 3) {
		printf("Expected 3 levels, but glGetTexParameteriv returned "
		       "%d for GL_TEXTURE_2D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	} else if (level != num_level) {
		printf("Expected queries of TEXTURE_IMMUTABLE_LEVELS and "
		       "TEXTURE_VIEW_NUM_LEVELS to return identical results.");
		piglit_report_result(PIGLIT_FAIL);
	}

	glBindTexture(GL_TEXTURE_3D, tex[2]);
	glTexStorage3D(GL_TEXTURE_3D, 3, GL_RGBA8, 32, 32, 32);
	glGetTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	glGetTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_VIEW_NUM_LEVELS, &num_level);
	if (level != 3) {
		printf("Expected 3 levels, but glGetTexParameterfv returned "
		       "%d for GL_TEXTURE_3D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	} else if (level != num_level) {
		printf("Expected queries of TEXTURE_IMMUTABLE_LEVELS and "
		       "TEXTURE_VIEW_NUM_LEVELS to return identical results.");
		piglit_report_result(PIGLIT_FAIL);
	}

	glBindTexture(GL_TEXTURE_2D, tex[3]);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_FLOAT, NULL);
	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	if (level != 0) {
		printf("Expected 0 levels, but glGetTexParameteriv returned "
		       "%d for GL_TEXTURE_2D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	}

	glBindTexture(GL_TEXTURE_3D, tex[4]);
	glTexImage2D(GL_TEXTURE_3D, 0, GL_RGBA, 32, 32, 32, GL_RGBA, GL_FLOAT, NULL);
	glGetTexParameteriv(GL_TEXTURE_3D, GL_TEXTURE_IMMUTABLE_LEVELS, &level);
	if (level != 0) {
		printf("Expected 0 levels, but glGetTexParameteriv returned "
		       "%d for GL_TEXTURE_3D.\n", level);
		piglit_report_result(PIGLIT_FAIL);
	}

	glDeleteTextures(5, tex);

	piglit_report_result(PIGLIT_PASS);
	return 0;
}
OceanSurface::OceanSurface(int N, int M, float L_x, float L_z, float A, glm::vec2 _wind, float g, bool _lines, bool _gpu) : N(N), M(M), L_x(L_x),
L_z(L_z), A(A), wind(_wind), g(g), lines(_lines), gpu(_gpu) {
	grid = new surface_vertex[N * M]; // construct wave height field grid
	init_positions = new vertex_2d[N * M];
	grid_tex_cord = new tex_img_coord[N * N];
	h_t0 = new complex_number[N * M];
	h_t0_cc = new complex_number[N * M];
	h_fft = new complex_number[N * M];
	dx_fft = new complex_number[N * M];
	dz_fft = new complex_number[N * M];
	gradient_x = new complex_number[N * M];
	gradient_z = new complex_number[N * M];
	lambda = -1.0f; // numeric constant for calculating displacement
	num_indices = 0;
	num_triangle_indices = 0;
	indices = new GLuint[(N - 1) * (M - 1) * 6 + 2 * (N + M - 2)];
	triangle_indices = new GLuint[(N - 1) * (M - 1) * 6 * 10];
	if (gpu) {
		wind = glm::vec2(wind.y, wind.x);
	}
	//fft
	myFFT = new MyFFT(N, M);

	// compute shader FFT stuff
	char *s_name = "compute_shaders/fft_compute.glsl";
	if (N == 32) {
		s_name = "compute_shaders/fft_compute_32.glsl";
	}
	if (N == 64) {
		s_name = "compute_shaders/fft_compute_64.glsl";
	}
	if (N == 128) {
		s_name = "compute_shaders/fft_compute_128.glsl";
	}
	if (N == 256) {
		s_name = "compute_shaders/fft_compute_256.glsl";
	}
	if (N == 512) {
		s_name = "compute_shaders/fft_compute_512.glsl";
	}
	fft_comp_program = create_comp_program_from_file(s_name);

	int bits = log2(N * 1.0f);
	calc_binary_reverse(bits);
	glGenBuffers(1, &rev_ind_buffer);
	glBindBuffer(GL_SHADER_STORAGE_BUFFER, rev_ind_buffer);
	glBufferData(GL_SHADER_STORAGE_BUFFER, N * sizeof(int), binary_reverse, GL_STATIC_DRAW);
	glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);

	GLint steps_location = glGetUniformLocation(fft_comp_program, "steps");
	fft_column_location = glGetUniformLocation(fft_comp_program, "fft_column");

	glUseProgram(fft_comp_program);
	glUniform1i(steps_location, bits);

	// texture for inpute height map
	glGenTextures(1, &texture_H_t);
	glBindTexture(GL_TEXTURE_2D, texture_H_t);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	//glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, N, N, 0, GL_RG, GL_FLOAT, 0);
	/*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/

	// texture for output height map per rows
	glGenTextures(1, &texture_H_fft_t_row);
	glBindTexture(GL_TEXTURE_2D, texture_H_fft_t_row);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	/*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/

	// texture for output height map per columns
	glGenTextures(1, &texture_H_fft_t_col);
	glBindTexture(GL_TEXTURE_2D, texture_H_fft_t_col);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	/*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/

	// texture for fft dx
	glGenTextures(1, &tex_dx_fft_row);
	glBindTexture(GL_TEXTURE_2D, tex_dx_fft_row);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	glGenTextures(1, &tex_dx_fft);
	glBindTexture(GL_TEXTURE_2D, tex_dx_fft);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);

	// texture for fft dz
	glGenTextures(1, &tex_dz_fft_row);
	glBindTexture(GL_TEXTURE_2D, tex_dz_fft_row);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	glGenTextures(1, &tex_dz_fft);
	glBindTexture(GL_TEXTURE_2D, tex_dz_fft);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);

	// texture for fft gradx
	glGenTextures(1, &tex_gradx_fft_row);
	glBindTexture(GL_TEXTURE_2D, tex_gradx_fft_row);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	glGenTextures(1, &tex_gradx_fft);
	glBindTexture(GL_TEXTURE_2D, tex_gradx_fft);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);

	// texture for fft gradz
	glGenTextures(1, &tex_gradz_fft_row);
	glBindTexture(GL_TEXTURE_2D, tex_gradz_fft_row);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	glGenTextures(1, &tex_gradz_fft);
	glBindTexture(GL_TEXTURE_2D, tex_gradz_fft);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);

	// unbind all textures
	glBindTexture(GL_TEXTURE_2D, 0);

	// assign each point its original 3d coordinates
	for (int i = 0; i < N; i++)
		for (int j = 0; j < M; j++) {
			int pos = i * M + j; // one-dimensional pos from linear two-dimensional grid

			grid_tex_cord[pos] = tex_img_coord(i, j);

			// precomputer amplitudes at each point
			h_t0[pos] = h_t_0(i, j);
			h_t0_cc[pos] = h_t_0(-i, -j).cc();

			// we project our N*M grid coordinates to real world L_x*L_z coordinates
			grid[pos].x = (i - (N >> 1)) * L_x / N;
			grid[pos].y = 0.0f; // height is 0
			grid[pos].z = (j - (M >> 1)) * L_z / M;

			// save initial positions
			init_positions[pos].x = grid[pos].x;
			init_positions[pos].z = grid[pos].z;

			// construct indices for index drawing
			if (i != N - 1 && j != M - 1) {
				indices[num_indices++] = pos;
				indices[num_indices++] = pos + 1;
				indices[num_indices++] = pos;
				indices[num_indices++] = pos + M;
				indices[num_indices++] = pos;
				indices[num_indices++] = pos + M + 1;
			}
			if (i != N - 1 && j == M - 1) {
				indices[num_indices++] = pos;
				indices[num_indices++] = pos + M;
			}
			if (i == N - 1 && j != M - 1) {
				indices[num_indices++] = pos;
				indices[num_indices++] = pos + 1;
			}

			// construct indices for triangle index drawing
			if (i != N - 1 && j != M - 1) {
				triangle_indices[num_triangle_indices++] = pos;
				triangle_indices[num_triangle_indices++] = pos + N + 1;
				triangle_indices[num_triangle_indices++] = pos + 1;

				triangle_indices[num_triangle_indices++] = pos;
				triangle_indices[num_triangle_indices++] = pos + N;
				triangle_indices[num_triangle_indices++] = pos + N + 1;
			}
		}

	// check that its okay
	assert(num_indices == (N - 1) * (M - 1) * 6 + 2 * (N + M - 2));
	//assert(num_triangle_indices, (N - 1) * (M - 1) * 6);

	prepare_for_pipeline();

	// update height map compute shader program
	upd_height_program = create_comp_program_from_file("compute_shaders/update_height_map.glsl");
	GLint len_location = glGetUniformLocation(upd_height_program, "L");;
	GLint n_location = glGetUniformLocation(upd_height_program, "N");
	total_time_location = glGetUniformLocation(upd_height_program, "totalTime");
	glUseProgram(upd_height_program);
	glUniform1f(len_location, L_x);
	glUniform1i(n_location, N);
	glUseProgram(0);

	// height map textures
	glGenTextures(1, &texture_H_t0);
	glGenTextures(1, &texture_H_t0_cc);
	glBindTexture(GL_TEXTURE_2D, texture_H_t0);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, N, N, GL_RG, GL_FLOAT, h_t0);
	glBindTexture(GL_TEXTURE_2D, texture_H_t0_cc);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, N, N, GL_RG, GL_FLOAT, h_t0_cc);
	glBindTexture(GL_TEXTURE_2D, 0);

	// displacement map textures
	glGenTextures(1, &texture_Dx);
	glGenTextures(1, &texture_Dz);
	glBindTexture(GL_TEXTURE_2D, texture_Dx);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	glBindTexture(GL_TEXTURE_2D, texture_Dz);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	glBindTexture(GL_TEXTURE_2D, 0);

	// gradient map textures
	glGenTextures(1, &texture_Gradx);
	glGenTextures(1, &texture_Gradz);
	glBindTexture(GL_TEXTURE_2D, texture_Gradx);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	glBindTexture(GL_TEXTURE_2D, texture_Gradz);
	glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N);
	glBindTexture(GL_TEXTURE_2D, 0);

	// Fresnel textures
	int fres_size = 128;
	float g_SkyBlending = 16.0f;
	unsigned int *buffer = new unsigned int[fres_size];
	for (int i = 0; i < fres_size; i++)
	{
		float cos_a = i / (float)fres_size;
		// Using water's refraction index 1.33
		unsigned int fresnel = (unsigned int)(D3DXFresnelTerm(cos_a, 1.33f) * 255);

		unsigned int sky_blend = (unsigned int)(powf(1 / (1 + cos_a), g_SkyBlending) * 255);

		buffer[i] = (sky_blend << 8) | fresnel;
	}
	glGenTextures(1, &tex_Fresnel);
	glBindTexture(GL_TEXTURE_1D, tex_Fresnel);
	glTexStorage1D(GL_TEXTURE_1D, 1, GL_RGBA8, fres_size);
	glTexSubImage1D(GL_TEXTURE_1D, 0, 0, fres_size, GL_RGBA, GL_UNSIGNED_INT, buffer);

	const GLfloat border[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	glTexParameterfv(GL_TEXTURE_1D, GL_TEXTURE_BORDER_COLOR, border);
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_COMPARE_FUNC, GL_NEVER);
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
	glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);

	glBindTexture(GL_TEXTURE_1D, 0);
	delete[] buffer;

	// Reflect cube textures
	tex_ReflectCube = SOIL_load_OGL_single_cubemap
		(
			"textures/sky_cube.dds",
			SOIL_DDS_CUBEMAP_FACE_ORDER,
			SOIL_LOAD_AUTO,
			SOIL_CREATE_NEW_ID,
			SOIL_FLAG_MIPMAPS | SOIL_FLAG_DDS_LOAD_DIRECT
		);
}