Jump to content

Recommended Posts

Posted (edited)

Hi,

 

I've got a little problem with my OpenGL code while drawing a rectangular texture:

  • thousands of little textures will be drawn instead of one texture
  • the texture to display is part of a larger texture, but the wrong part of this huge "spritesheet" is drawn
  • those thousands of little textures are drawn on the wrong place of the screen

 

  • `guiStartX` and `guiStartY`: the x and y positions where the GUI should start
  • `textureX` and `textureY`: the position in the "spritesheet" where the texture can be found
  • `width` and `height`: the width and height of the texture to draw

 

 

mc.getTextureManager().bindTexture(UI_PROGRESS_TEXTURE);
int guiStartX = (mc.displayWidth - 16) / 2;
	int guiStartY = (mc.displayHeight - 51) / 2;
	renderTexturedRect(guiStartX, guiStartY, 176, 51, 16, 51);

renderTexturedRect(int x, int y, int textureX, int textureY, int width, int height) {
	glBegin(GL_QUADS);
	    glTexCoord2f(textureX, textureY);
	    glVertex3i(0, 0, 0);
	    
	    glTexCoord2f(textureX, textureY + height);
	    glVertex3i(0, height + 400, 0);
	    
	    glTexCoord2f(textureX + width, textureY + height);
	    glVertex3i(width + 800, height + 400, 0);
	    
	    glTexCoord2f(textureX + width, textureY);
	    glVertex3i(width + 800, 0, 0);
	    glEnd();

 

  1. One may ask, why not using drawTexturedModalRect from Minecraft itself. The Reason for this is that it is not available in the place where I am drawing.

  2. And why am I using OpenGL directly instead of for example looking into how drawTexturedModalRect renders a rectangle and doing it the same way?:

    The answer to this is that I am rather using OpenGL directly instead of using undocumented code where I do not even know what it is doing and how the stuff is getting onto the screen with using this (like where and which OpenGL calls are being called etc.)

 

Note: I am not familiar with OpenGL 2.1 nor with LWJGL 2 as I've only worked with OpenGL 4.5 (in C++) and it's shaders so far (and very little with LWJGL 3).

 

Thx in advance.

Bektor

Edited by Bektor

Developer of Primeval Forest.

Posted
  On 8/8/2017 at 11:52 PM, Bektor said:

One may ask, why not using drawTexturedModalRect from Minecraft itself. The Reason for this is that it is not available in the place where I am drawing.

Expand  

Where are you doing this, then?

 

Also, you're not binding a texture.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted
  On 8/8/2017 at 11:52 PM, Bektor said:
  • thousands of little textures will be drawn instead of one texture
  • the texture to display is part of a larger texture, but the wrong part of this huge "spritesheet" is drawn
Expand  

UVs must be within a range of [0-1] and you are passing a range of [0-16] x [0-51]. That won't work well. By default all MC textures have their wrap S/T set to repeat, and that's why you see "thousands of little textures" - it is actually your texture repeated 16 times on the x axis and 51 times on the y axis.

 

  On 8/8/2017 at 11:52 PM, Bektor said:

those thousands of little textures are drawn on the wrong place of the screen

Expand  

Well, where are you expecting to see your quad? We can't tell what is wrong with the UI positioning just by looking at the code - although I can take a guess: you should subtract your position offsets after you've found the center of the screen.

 

  On 8/8/2017 at 11:52 PM, Bektor said:

One may ask, why not using drawTexturedModalRect from Minecraft itself. The Reason for this is that it is not available in the place where I am drawing.

Expand  

There is absolutely nothing stopping you from using static methods in the GUI class. Or copying the method for that matter.

 

  On 8/8/2017 at 11:52 PM, Bektor said:

The answer to this is that I am rather using OpenGL directly instead of using undocumented code where I do not even know what it is doing and how the stuff is getting onto the screen with using this

Expand  

I still suggest using BufferBuilder/VertexBuffer rather than OpenGL directly. There is a reason MC switched to it entirely. And well, some people might assume that all drawing is indeed done using methods from that class and abuse that.

Posted

Also, why don't use make use of x and y?

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Posted
  On 8/9/2017 at 1:36 AM, V0idWa1k3r said:

Well, where are you expecting to see your quad? We can't tell what is wrong with the UI positioning just by looking at the code - although I can take a guess: you should subtract your position offsets after you've found the center of the screen.

 

Expand  

Well, I want to place it in the middle of the screen.

  On 8/9/2017 at 1:52 AM, Abastro said:

Also, why don't use make use of x and y?

Expand  

Well, I used them, thought it didn't went that good. Couldn't see the image anymore, so I started fixing the image first to get it properly drawn as one big image is easier to see then thousands of small images.

 

  On 8/9/2017 at 1:36 AM, V0idWa1k3r said:

I still suggest using BufferBuilder/VertexBuffer rather than OpenGL directly. There is a reason MC switched to it entirely. And well, some people might assume that all drawing is indeed done using methods from that class and abuse that.

Expand  

I don't see any reason why BufferBuilder/VertexBuffer is the prefered way, especially when I do not know how it is connected to the hole rendering system and how those two classes work internally.

 

  On 8/9/2017 at 1:36 AM, V0idWa1k3r said:

UVs must be within a range of [0-1] and you are passing a range of [0-16] x [0-51]. That won't work well. By default all MC textures have their wrap S/T set to repeat, and that's why you see "thousands of little textures" - it is actually your texture repeated 16 times on the x axis and 51 times on the y axis.

 

Expand  

Hm, now I am wondering, where does MC the conversion? I mean, when calling drawTexturedModalRect I don't think I ever passed the width of the complete image to draw, only the position and width and height of the part of the image to be drawn nor is the texture passed.

Developer of Primeval Forest.

Posted
  On 8/9/2017 at 10:41 AM, Bektor said:

Well, I want to place it in the middle of the screen.

Expand  

Position it in the middle of the screen then. It would be screenWidth/2 - yourWidth/2, screenHeight/2 - yourHeight/2.

 

  On 8/9/2017 at 10:41 AM, Bektor said:

I don't see any reason why BufferBuilder/VertexBuffer is the prefered way, especially when I do not know how it is connected to the hole rendering system and how those two classes work internally.

Expand  

It is preferred because it is conventional. I mean in theory you can use java's ImageIO to load images from an InputStream, upload their pixel data to a buffer, setup a GLtexture and link the buffer to the texture every time you need a texture but you are not doing that, are you? Instead you use TextureManager::bindTexture. Same goes for BufferBuilder. And as I've said:

  On 8/9/2017 at 1:36 AM, V0idWa1k3r said:

And well, some people might assume that all drawing is indeed done using methods from that class and abuse that.

Expand  

As to how it worksL it basically has an internal buffer it fills with data you pass to it. The offsets, strides and elements/vertex are controlled by the VertexFormat specified. Once you invoke draw the buffer is passed to OpenGL and rendered. It is somewhat of a complex yet very flexible wrapper around GL 3.0+ rendering. If you are familiar with GL4.5 you should be familiar with this aswell. As a side bonus it allows for "modern" shaders to be used(and MC does that in some cases).

 

  On 8/9/2017 at 10:41 AM, Bektor said:

Hm, now I am wondering, where does MC the conversion? I mean, when calling drawTexturedModalRect I don't think I ever passed the width of the complete image to draw, only the position and width and height of the part of the image to be drawn nor is the texture passed.

Expand  

Let's look at Gui::drawTexturedModalRect. Specifically at it signature:

public void drawTexturedModalRect(int x, int y, int textureX, int textureY, int width, int height)

The parameters I've marked as bold are to be processed into UVs in the method. textureX/Y are the start, and textureX/Y + width/height are the end. How are they processed? Well, let's look into that method. You will quickly notice that the results of manipulations with these values are multiplied by 0.00390625F. What is this magical number? It is 1/256. MC assumes the height/width of a GUI icon to be 256x256 and does calculations based on that assumption. If the texture is bigger in size(say via a resourcepack) it actually does not matter as the range of [0-1] is effectively a percentage and if the code is based around a 256x256 assumption(the variables passed to this method, that is) the end-result percentages are still going to be correct regardless of the texture width/height. 

 

Posted
  On 8/9/2017 at 11:03 AM, V0idWa1k3r said:

Let's look at Gui::drawTexturedModalRect. Specifically at it signature:

public void drawTexturedModalRect(int x, int y, int textureX, int textureY, int width, int height)

The parameters I've marked as bold are to be processed into UVs in the method. textureX/Y are the start, and textureX/Y + width/height are the end. How are they processed? Well, let's look into that method. You will quickly notice that the results of manipulations with these values are multiplied by 0.00390625F. What is this magical number? It is 1/256. MC assumes the height/width of a GUI icon to be 256x256 and does calculations based on that assumption. If the texture is bigger in size(say via a resourcepack) it actually does not matter as the range of [0-1] is effectively a percentage and if the code is based around a 256x256 assumption(the variables passed to this method, that is) the end-result percentages are still going to be correct regardless of the texture width/height. 

Expand  

Changing my code to multiply the texture values with 1/256 just let's the complete image disappear.

        glTexCoord2f(textureX * (1/256), textureY * (1/256));
	    glVertex3i(0, 0, 0);
	    
	    glTexCoord2f(textureX * (1/256), (textureY + height) * (1/256));
	    glVertex3i(0, height + 400, 0);
	    
	    glTexCoord2f((textureX + width) * (1/256), (textureY + height) * (1/256));
	    glVertex3i(width + 800, height + 400, 0);
	    
	    glTexCoord2f((textureX + width) * (1/256), textureY * (1/256));
	    glVertex3i(width + 800, 0, 0);

 

  On 8/9/2017 at 11:03 AM, V0idWa1k3r said:

It is somewhat of a complex yet very flexible wrapper around GL 3.0+ rendering.

Expand  

Hm, why the hell creates Mojang wrappers around GL 3.0+ rendering instead of using it direclty. I mean, I don't know any graphics card today which doesn't support OpenGL 3.0+, even NVIDIAs GTX 400 series supports OpenGL 4.6 with the newest beta drivers and 4.5 with the newest stable drivers.

Developer of Primeval Forest.

Posted
  On 8/9/2017 at 11:58 AM, Bektor said:

Changing my code to multiply the texture values with 1/256 just let's the complete image disappear.

Expand  

Your textureX/Y are of an integer type. So is 1. And so is 256. Dividing an integer 1 by an integer 256 prouces you 0 and well, anything *0 is 0.

 

  On 8/9/2017 at 11:58 AM, Bektor said:

Hm, why the hell creates Mojang wrappers around GL 3.0+ rendering instead of using it direclty.

Expand  

Why do people create abstractions to begin with? Let's all write our code in assembly! That is sure going to be fun! :P

On a serious note - their BufferBuilder is very flexible - and that is why they did it. As long as you have the format you can easily upload anything you want to it and render it as desired without having to manualy setup GL buffers/arrays/attributes/younameit every time. Heck, you can even have custom formats defined and it will work just fine. Also it allows to easily modify the individual elements of the buffer if needed after they've been uploaded with a single method invocation. Doing it on a raw buffer is... A bit more challenging.

 

  On 8/9/2017 at 11:58 AM, Bektor said:

don't know any graphics card today which doesn't support OpenGL 3.0+

Expand  

And yet a lot of people had issues with MC starting to require OpenGL 3.3. I remember having one myself on a linux machine at work due to the way mesa drivers are done.

Posted (edited)
  On 8/9/2017 at 12:04 PM, V0idWa1k3r said:

Your textureX/Y are of an integer type. So is 1. And so is 256. Dividing an integer 1 by an integer 256 prouces you 0 and well, anything *0 is 0.

 

Expand  

Always forget this one thing, but it didn't solve the problem. The texture is still gone:

	    glTexCoord2f(textureX * (1.f / 256.f), textureY * (1.f / 256.f));
	    glVertex3i(0, 0, 0);
	    
	    glTexCoord2f(textureX * (1.f / 256.f), (textureY + height) * (1.f / 256.f));
	    glVertex3i(0, height + 400, 0);
	    
	    glTexCoord2f((textureX + width) * (1.f / 256.f), (textureY + height) * (1.f / 256.f));
	    glVertex3i(width + 800, height + 400, 0);
	    
	    glTexCoord2f((textureX + width) * (1.f / 256.f), textureY * (1.f / 256.f));
	    glVertex3i(width + 800, 0, 0);

Hope I didn't forgot a small thing again, thought somehow I hope I did as it would solve the problem faster. ^^

 

  On 8/9/2017 at 12:04 PM, V0idWa1k3r said:

Why do people create abstractions to begin with? Let's all write our code in assembly! That is sure going to be fun! :P

Expand  

Assembly makes fun. You can even enforce a PC configuration with this as it won't run anywhere else. xD But why using Assembly, binary with its 01010101 is even better. :P 

 

  On 8/9/2017 at 12:04 PM, V0idWa1k3r said:

And yet a lot of people had issues with MC starting to require OpenGL 3.3. I remember having one myself on a linux machine at work due to the way mesa drivers are done.

Expand  

I don't know much about Mesa drivers, except that they got a somewhat stable OpenGL 4.5 support, but why not using official drivers?

And I don't think Minecraft uses OpenGL 3.3, the last version I know for sure they are using is OpenGL 2.1.

Edited by Bektor

Developer of Primeval Forest.

Posted (edited)
  On 8/9/2017 at 12:21 PM, Bektor said:

The texture is still gone:

Expand  

Hm, interesting. Can you please elaborate on the word 'gone' in your scenario? I have debugged your code and had no issues with it - apart from the fact that it is rendered across the entire screen(I've got that fixed in my test) and the UVs point at a relatively small region of the image.

  Reveal hidden contents

 

Edited by V0idWa1k3r
Posted (edited)
  On 8/9/2017 at 12:52 PM, V0idWa1k3r said:

Hm, interesting. Can you please elaborate on the word 'gone' in your scenario? I have debugged your code and had no issues with it - apart from the fact that it is rendered across the entire screen and the UVs point at a relatively small region of the image.

  Reveal hidden contents
Expand  

Ok, fixed it with changing the first 51 parameter from my method to 0.

 

  On 8/9/2017 at 12:52 PM, V0idWa1k3r said:

Here is my test sample:

Expand  

Hm, I'm wondering what this invoke method is.

Edited by Bektor

Developer of Primeval Forest.

Posted (edited)
  On 8/9/2017 at 1:08 PM, Bektor said:

Even when implementing your ScaledResolution thing, it is still not drawn in the screen. Also when changing my glVertex3i to yours it is not drawn inside of the screen.

Expand  

I suppose that would be because of these lines:

  On 8/9/2017 at 1:08 PM, Bektor said:

int guiStartX = (sRes.getScaledWidth() - 16) / 2;

int guiStartY = (sRes.getScaledHeight() - 51) / 2;

Expand  

 

  On 8/9/2017 at 1:08 PM, Bektor said:

Hm, I'm wondering what this invoke method is.

Expand  

A part of my testing framework that I use to debug code from people when I do not see an obvious issue.

 

  On 8/9/2017 at 1:08 PM, Bektor said:

With gone I mean that it is nowhere to be seen on the screen as if it wouldn't be rendered at all, thought the code to render it is still be called.

Expand  

Well, I am at a loss here then as this identical code works for me. If you don't mind could you please setup a github repo of your project(or a minimal part of it that allows the issue to be reproduced reliably) that can be cloned and debugged locally. I could then debug it with your exact conditions to try to figure out what exactly is wrong.

EDIT: even though you've fixed it I am still curious as to what the issue was exactly. Was it a texture issue? 

Edited by V0idWa1k3r
Posted (edited)
  On 8/9/2017 at 1:16 PM, V0idWa1k3r said:
  On 8/9/2017 at 1:08 PM, Bektor said:

int guiStartX = (sRes.getScaledWidth() - 16) / 2;

int guiStartY = (sRes.getScaledHeight() - 51) / 2;

Expand  

 

Expand  

Fixed with changing the first 51 parameter from my method to 0. The ScaledResolution thing also solved problems with disappering textures when changing the screen size, which I didn't even noticed before. :) 

 

  On 8/9/2017 at 1:16 PM, V0idWa1k3r said:

EDIT: even though you've fixed it I am still curious as to what the issue was exactly. Was it a texture issue? 

Expand  

I suppose it was an issue with missing ScaledResolution and me having the reading direction for OpenGL texture coordinates wrong in my head.

Edited by Bektor

Developer of Primeval Forest.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

  Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

  Your link has been automatically embedded.   Display as a link instead

  Your previous content has been restored.   Clear editor

  You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Create New...

Important Information

By using this site, you agree to our Terms of Use.