Java-Gaming.org Hi !
Featured games (91)
games approved by the League of Dukes
Games in Showcase (804)
Games in Android Showcase (239)
games submitted by our members
Games in WIP (868)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Minimalist Complete Texture  (Read 12733 times)
0 Members and 1 Guest are viewing this topic.
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Posted 2016-06-04 23:46:04 »

So I know in order for a texture to be complete, it needs a mipmap defined. Or so I know.

To load PNG files, I use TWL class.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
   public static TextureData loadTexture(String location) throws IOException {
      final int tid = glGenTextures();
      final FileInputStream fis = new FileInputStream(location);
      final PNGDecoder decoder = new PNGDecoder(fis);
      final int width = decoder.getWidth(), height = decoder.getHeight();
      final ByteBuffer bb = BufferUtils.createByteBuffer(width * height * 4);
      decoder.decode(bb, decoder.getWidth() * 4, PNGDecoder.Format.RGBA);
      bb.flip();
      fis.close();
      glBindTexture(GL_TEXTURE_2D, tid);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
      //TODO: Add min and max mipmap stuff for finished texture
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bb);
      glBindTexture(GL_TEXTURE_2D, 0);
      final TextureData t = new TextureData(tid, location, width, height);
      Textures.add(t);
      return t;
   }


I am not asking for code, but I am asking for code. What do I put at the //TODO: to make this a complete texture?

Alongside of that, the original intent of this post was to ask why make a complete texture and is it necessary or beneficial.

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Offline ShadedVertex
« Reply #1 - Posted 2016-06-05 11:23:19 »

Why make a complete texture? Well, you can only use a texture if it's complete. If it's an incomplete texture, the texture won't work and you can't use it.

Quote
1  
2  
3  
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pixels);


The texture won't work because it is incomplete. The default GL_TEXTURE_MIN_FILTER state is GL_NEAREST_MIPMAP_LINEAR. And because OpenGL defines the default GL_TEXTURE_MAX_LEVEL to be 1000, OpenGL will expect there to be mipmap levels defined. Since you have only defined a single mipmap level, OpenGL will consider the texture incomplete until the GL_TEXTURE_MAX_LEVEL is properly set, or the GL_TEXTURE_MIN_FILTER parameter is set to not use mipmaps.

You have already set up texture filtering with the glTexParameteri function, and you set the mipmap level to 0 in the glTexImage2D function. Your texture is complete, don't worry Cheesy
Offline theagentd
« Reply #2 - Posted 2016-06-05 15:13:19 »

A texture is complete if all used mipmaps are defined.
 - If your minification filtering doesn't include mipmaps, you only need to define the first level.
 - If your minification filtering DOES include mipmaps, all mipmaps from GL_TEXTURE_BASE_LEVEL to GL_TEXTURE_MAX_LEVEL (inclusive, these are settable with glTexParameteri()). If BASE=0 and MAX=0, then you only need to set level 0 for example.
 - If you create your texture with the glTexStorage*D(), all mipmaps will be allocated immediately and the BASE and MAX levels set automaitcally, so the texture is technically complete (but still filled with garbage/uninitialized memory).

Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline basil_

« JGO Bitwise Duke »


Medals: 418
Exp: 13 years



« Reply #3 - Posted 2016-06-05 20:46:12 »

so to be sure. if not using glTexStorage, create texture with
1  
2  
GL11.glTexParameteri(bindTarget,GL12.GL_TEXTURE_BASE_LEVEL,baseLevel);
GL11.glTexParameteri(bindTarget,GL12.GL_TEXTURE_MAX_LEVEL,maxLevel);

and create mipmaps with
EXTDirectStateAccess.glGenerateTextureMipmapEXT(id,target)
or
GL30.glGenerateMipmap(target)
to allocate memory (even with garbage if base_level is undefined) to avoid out-of-memory errors mid-air later on. like using a ton of g-buffers with mipmaps.

btw :

GL_TEXTURE_MAX_LEVEL =  1 + floor(log2(max(width,height,depth)))


and

width_at(mip_level) = max(1,floor(width/pow(2,mip_level)))

height_at(mip_level) = max(1,floor(height/pow(2,mip_level)))
and so on.

o/
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #4 - Posted 2016-06-05 23:04:13 »

Okay so from what I compiled from these brilliant replies (thanks guys), I understand that this code goes without any garbage data/uninit data (because from what I comprehended, 1000 images will be created??).
1  
2  
3  
4  
5  
6  
7  
8  
9  
      glBindTexture(GL_TEXTURE_2D, tid);
      glTexParameteri(GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0);
      glTexParameteri(GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bb);
      glBindTexture(GL_TEXTURE_2D, 0);


Because I set the mipmap level to 0 base and max.

If I ever support mipmapping, I should a function to directly alter the mipmaps.
As Basil_ said,
Quote
EXTDirectStateAccess.glGenerateTextureMipmapEXT(id,target) or GL30.glGenerateMipmap(target)

I think using EXT and ARB is kindof gross looking, but idk. I am not going to bias it before I understand it fully, which this isn't the topic to learn about it right now.

But Basil_, what did you mean by:
Quote
GL_TEXTURE_MAX_LEVEL =  1 + floor(log2(max(width,height,depth)))

and

width_at(mip_level) = max(1,floor(width/pow(2,mip_level)))
height_at(mip_level) = max(1,floor(height/pow(2,mip_level)))

and so on.

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Offline basil_

« JGO Bitwise Duke »


Medals: 418
Exp: 13 years



« Reply #5 - Posted 2016-06-06 00:10:40 »

width, height, depth are texture properties. these methods compute the max-mip-level possible with a texture and compute the dimension at a specific mip level - in case you need them while fiddling with textures.

that EXT is DSA, if you find any method that is DSA but not EXT you're better of using that one but there are not that many around.
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #6 - Posted 2016-06-06 00:13:51 »

Right, right it was a little ambiguous.

So I assume that what I wrote did what I thought.

Thanks for everything, basil_, ShadedVertex, and theagentd!

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Offline theagentd
« Reply #7 - Posted 2016-06-06 02:58:22 »

Some advanced tips:
 - glGenerateMipmaps() is sRGB correct. It automatically does sRGB correct downsampling (sRGB --> linear, downsample, linear --> sRGB) if the format is an sRGB format.
 - Do not use glGenerateMipmaps() in real-time running code as it doesn't have optimal performance. Use a simple texture read shader or glBlitFramebuffer() to downsample a texture. It also breaks SLI completely if used in the rendering loop as it forces synchronization between GPUs.
 - Always precompress compressed textures and load the compressed data directly. Although driver support for compressing textures is mandatory, the quality and performance varies a lot. Intel's driver takes ages to do BPTC (~2 minutes to compress our skybox).
 - The driver always seem to allocate all mipmaps up to the mipmap level allocated, regardless of BASE_LEVEL. Example: If you allocate mipmap level 1 first, 0 will also be (invisibly) allocated and use up texture memory. I once tried to reduce memory usage by not loading mipmap 0 and setting BASE_LEVEL to 1, but memory usage in GPU-Z was the same as if I had loaded mipmap level 1 too. Worst texture quality setting ever. It's therefore almost never useful to modify BASE_LEVEL unless it is to temporarily limit texture sampling to certain mipmaps.
 - AMD's driver is unreliable when it comes to texture loading. I strongly recommend using glTexStorage() instead of glTexImage() if it's available. If not, use glTexImage() with a null buffer to allocate all mipmap levels before you start uploading them. I've encountered numerous driver crashes and problems by doing it any other way. Mostly true if you're doing texture streaming with a separate context and/or using compressed textures.

Myomyomyo.
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #8 - Posted 2016-06-06 03:32:23 »

I can't find anything online that documents what you were trying to say about glTexStorage and from what I read it is also used with glTexSubImage or whatever. Could you please give an example.

Also, I target OpenGL 3,2 currently. As I read, it's a OpenGL 4,4 feature. I am not sure though.

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Offline theagentd
« Reply #9 - Posted 2016-06-06 13:31:29 »

I can't find anything online that documents what you were trying to say about glTexStorage and from what I read it is also used with glTexSubImage or whatever. Could you please give an example.

Also, I target OpenGL 3,2 currently. As I read, it's a OpenGL 4,4 feature. I am not sure though.
glTexStorage() allocates the memory for all mipmaps (= calling glTexImage(..., null) for all mipmaps) and makes the texture immutable, so you can't change the size or allocate more mipmaps after that (you can't call glTexStorage() or glTexImage() again on that texture). Hence, the texture has to be complete at this point, since if it wasn't you would be forced to delete it and start over. The contents of the texture mipmaps still aren't "initialized", as in we haven't specified the colors of each pixel yet, which must be done with glTexSubImage(), which modifies an already allocated texture.

There's a difference between allocating memory and updating the contents of allocated memory. glTexStorage() only allocates memory without updating it (and prevents you from reallocating it), glTexSubImage() only updates memory without being able to allocate new memory, and glTexImage() both updates and allocates/reallocates memory.

And yes, it is an OpenGL 4.4 feature, but you can always use a 3.2 context and use glTexStorage() is the extension for it is supported, falling back to a glTexImage() loop if it's not supported. Like I said, glTexStorage() seems a lot more solid for the AMD driver.

Myomyomyo.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #10 - Posted 2016-06-06 23:28:07 »

glTexStorage() allocates immutable memory
glTexSubImage() writes to allocated memory
glTexImage() allocates mutable memory and writes to it, but no mipmap support

Thats what I got out of this.

How do I check if the extension is supported?

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Offline theagentd
« Reply #11 - Posted 2016-06-07 00:45:47 »

glTexImage() allocates mutable memory and writes to it, but no mipmap support
It allocates ONE mipmap level per call, so it does have mipmap support. You just have to call it once per mipmap to manually allocate them.

I guess glGenerateMipmaps() also qualifies for this list:

glGenerateMipmaps() allocates (or reallocates) all mipmaps from BASE_LEVEL+1 to MAX_LEVEL, and replaces their contents with repeatedly downsampled data from BASE_LEVEL.

Myomyomyo.
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #12 - Posted 2016-06-07 04:32:17 »

Hmm... something popped up a bit ago that had me questioning.

I recently was adding multitexture support for... entities in general...

1  
2  
3  
4  
5  
   public void bindTexture(int target, int location, int unit, int tid) {
      GL13.glActiveTexture(GL13.GL_TEXTURE0 + unit);
      GL11.glBindTexture(target, tid);
      bindUniformi(location, unit);
   }


So as you see, I select the active texture unit and bind a texture. I then call bindUniformi(location, unit)... however... that just seems wrong. Would that be mipmap level? This is the part where I bind to a sampler2D.

1  
shader.bindTexture(GL11.GL_TEXTURE_2D, u_texture[i], i, material.getTextureData().getId());

u_texture refers to a getUniformLocation() call. I have a table of these locations in the shader. Would the 'unit' part of bindUniformi(location, unit) be correct, or is this mipmap?

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
   public void bindUniformi(int location, int... uni) {
      switch(uni.length) {
      case 1:
         GL20.glUniform1i(location, uni[0]);
         break;
      case 2:
         GL20.glUniform2i(location, uni[0], uni[1]);
         break;
      case 3:
         GL20.glUniform3i(location, uni[0], uni[1], uni[2]);
         break;
      case 4:
         GL20.glUniform4i(location, uni[0], uni[1], uni[2], uni[3]);
         break;
      }
   }

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #13 - Posted 2016-06-12 08:53:19 »

I've used this thread for a lot of reference recently.

I wanted to add that my game engine sports this complete texture business.

Also, it appears that I support opengl 2.0  Pointing

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Offline theagentd
« Reply #14 - Posted 2016-06-12 14:23:49 »

The best solution is this: Right after creating your shader, you bind it and set the texture units of each sampler.

1  
2  
3  
4  
5  
6  
7  
8  
//set up shaders with glAttachShader(program, ...)
glLinkProgram(program);

glUseProgram(program);
glUniform1i(glGetUniformLocation(program, "firstSampler"), 0);
glUniform1i(glGetUniformLocation(program, "secondSampler"), 1);
glUniform1i(glGetUniformLocation(program, "thirdSampler"), 2);
//etc


These uniform values will then be permanently stored in the program and persists when switching shaders (each program has its own uniform values; uniform values are not global state). Hence, you won't ever have to worry about updating the samplers again. Just bind the first texture to texture unit 0 to make it readable by firstSampler, to unit 1 to make it readable by secondSampler, etc.

Myomyomyo.
Offline basil_

« JGO Bitwise Duke »


Medals: 418
Exp: 13 years



« Reply #15 - Posted 2016-06-12 19:57:30 »

that one always bites me when doing live-coding. "re-linking" requires the uniforms to be set again.

subroutines are not stored that way btw. they need to be set every time the program is used.

Offline Hydroque

JGO Coder


Medals: 25
Exp: 5 years


I'm always inspiring a good time.


« Reply #16 - Posted 2016-06-13 00:38:43 »

The best solution is this: Right after creating your shader, you bind it and set the texture units of each sampler.

1  
2  
3  
4  
5  
6  
7  
8  
//set up shaders with glAttachShader(program, ...)
glLinkProgram(program);

glUseProgram(program);
glUniform1i(glGetUniformLocation(program, "firstSampler"), 0);
glUniform1i(glGetUniformLocation(program, "secondSampler"), 1);
glUniform1i(glGetUniformLocation(program, "thirdSampler"), 2);
//etc


These uniform values will then be permanently stored in the program and persists when switching shaders (each program has its own uniform values; uniform values are not global state). Hence, you won't ever have to worry about updating the samplers again. Just bind the first texture to texture unit 0 to make it readable by firstSampler, to unit 1 to make it readable by secondSampler, etc.

I have a new model in mind, which accepts a number of units to use, which binds all necessary samplers. There is then the portion which actually sets the data to these locations. These are called initially from a list of texture handles. Any post will be done over.

You think I haven't been monitoring the chat? http://pastebin.java-gaming.org/c47d35366491fHere is a compilation <3
Pages: [1]
  ignore  |  Print  
 
 

 
Riven (581 views)
2019-09-04 15:33:17

hadezbladez (5511 views)
2018-11-16 13:46:03

hadezbladez (2403 views)
2018-11-16 13:41:33

hadezbladez (5773 views)
2018-11-16 13:35:35

hadezbladez (1225 views)
2018-11-16 13:32:03

EgonOlsen (4663 views)
2018-06-10 19:43:48

EgonOlsen (5683 views)
2018-06-10 19:43:44

EgonOlsen (3198 views)
2018-06-10 19:43:20

DesertCoockie (4095 views)
2018-05-13 18:23:11

nelsongames (5115 views)
2018-04-24 18:15:36
A NON-ideal modular configuration for Eclipse with JavaFX
by philfrei
2019-12-19 19:35:12

Java Gaming Resources
by philfrei
2019-05-14 16:15:13

Deployment and Packaging
by philfrei
2019-05-08 15:15:36

Deployment and Packaging
by philfrei
2019-05-08 15:13:34

Deployment and Packaging
by philfrei
2019-02-17 20:25:53

Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!