Sorry if question is a bit niche. I wrote some code a few years back and it renders many meshes as 1 big mesh for performance.
What I am trying to do now is just render meshes without textures, so a single colour
boxModel = modelBuilder.createBox(10f, 10f, 10f, Material(ColorAttribute.createDiffuse(Color.WHITE), ColorAttribute.createSpecular(Color.RED), FloatAttribute.createShininess(15f)), (VertexAttributes.Usage.Position or VertexAttributes.Usage.Normal or VertexAttributes.Usage.TextureCoordinates).toLong()) // or VertexAttributes.Usage.TextureCoordinates
for (x in 1..10) {
for (y in 1..10) {
modelInstance = ModelInstance(boxModel, x * 15f, 0.0f, y * 15f)
chunks2[0].addMesh(modelInstance.model.meshes, modelInstance.transform, btBoxShape(Vector3(10f, 10f, 10f)))
}
}
chunks2[0].mergeBaby()
So I build up the giant mesh and then render it
shaderProgram.begin()
texture.bind()
shaderProgram.setUniformMatrix("u_projTrans", camera.combined)
shaderProgram.setAttributef("a_color", 1f, 1f, 1f, 1f)
shaderProgram.setUniformi("u_texture", 0)
renderChunks()
shaderProgram.end()
This works for textured stuff great and the right texture is shown etc but the base colour (I guess that's "a_color" is set to white) where I actually want it to use what I supplied in the Material property.
Related
There is a bunch of 2x2 "floor/tiles" in a 3D-world with JOGL, they are projected into the camera and I want to know the cursor is hovering the tile or not.
I have a camera settings like this:
glu.gluPerspective(90, 4.0/3.0, 1, 100);
glu.gluLookAt(-2f, 8f, -2f, 0f, 0f, 0f, 0f, 1f, 0f);
and there are some tiles or blocks on the y=0 pane like this
gl.glPushMatrix();
{
// Camera settings (same as above)
glu.gluPerspective(90, 4.0/3.0, 1, 100);
glu.gluLookAt(-2f, 8f, -2f, 0f, 0f, 0f, 0f, 1f, 0f);
// Draw the tiles
gl.glPushMatrix();
{
gl.glBegin(GL2.GL_POLYGON);
{
// a bunch of translated and textured
// (1,0,1) (1,0,-1) (-1,0,-1) (-1,0,1)
// rectangle here,
}
gl.glEnd();
}
gl.glPopMatrix();
}
gl.glPopMatrix();
I am new in 3D and I am only familiar with Java Graphics2D. Intersection of 2D rectangle and cursor is just a few easy comparison, but it seems to be a lot more complicated in 3D. I am looking for some Maths or library to do this.
Or if there is a method to get the 4 point of the final pixels on the screen, Maybe I would like to do java.awt.Shape contain() and check it intersects or not.
The result will be like this:
Maybe the simplest solution is using the gluProject(); to get the screen coordinate, and using java.awt.geom.Path2D to check the mouse coordinate is in the area or not.
Here is a simple sample code:
// do inside the matrix stack? of rendering rectangles to get the right matrix we want
float[][] FinalCoordinate = new float[4][4];
float[] ModelView = new float[16];
float[] Projection = new float[16];
gl.glGetFloatv(GL2.GL_MODELVIEW_MATRIX,ModelView,0);
gl.glGetFloatv(GL2.GL_PROJECTION_MATRIX,Projection,0);
for(int x = 0; x < 4; x++)
{
glu.gluProject(Vertex[x][0],0f,Vertex[x][2],ModelView,0,Projection,0,new int[]{0,0,800,600},0,FinalCoordinate[x],0);;
}
after getting four points of the final coorindates, use Path2D to check the intersection:
Path2D p = new Path2D.Float();
p.moveTo(FinalCoordinate[0][0],FinalCoordinate[0][1]);
for(int x = 1;x<4;k++)
{
p.lineTo(fc[x][0],fc[x][1]);
}
p.closePath();
boolean Result = p.contains(MouseX, MouseY);
thats it! Thanks those suggestions and links :)
I'm making a weather simulation in Opengl 4.0 and am trying to create the sky by creating a fullscreen quad in the background. I'm trying to do that by having the vertex shader generate four vertexes and then drawing a triangle strip. Everything compiles just fine and I can see all the other objects I've made before, but the sky is nowhere to be seen. What am I doing wrong?
main.cpp
GLint stage = glGetUniformLocation(myShader.Program, "stage");
//...
glBindVertexArray(FS); //has four coordinates (-1,-1,1) to (1,1,1) in buffer object
glUniform1i(stage, 1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
vertex shader
uniform int stage;
void main()
{
if (stage==1)
{
gl_Position = vec4(position, 1.0f);
}
else
{
//...
}
}
fragment shader
uniform int stage;
void main()
{
if (stage==1)
{ //placeholder gray colour so I can see the sky
color = vec4(0.5f, 0.5f, 0.5f, 1.0f);
}
else
{
//...
}
}
I should also mention that I'm a beginner in OpenGL and that it really has to be in OpenGL 4.0 or later.
EDIT:
I've figured out where's the problem, but still don't know how to fix it. The square exists, but only displays if I multiply it with the view and projection matrix (but then it doesn't stay glued to the screen and just rotates along with the rest of the scene, which I do not want). Essentially, I somehow need to switch back to 2D or to screen space or however it's called, draw the square, and switch back to 3D so that all the other objects work fine. How?
The issue was with putting a 1 as the z coord – putting 0.999f instead solved the issue.
I am working on a game project using LibGDX. Now I'm facing a problem I can't understand; let me explain what I've got before coming to the actual problem:
Static background C (tiled)
Moving background B (tiled)
Moving background A (tiled)
Characters, entities
Walls (tiled)
HUD
The render loop goes as follows:
Render 2 to 5 in previous list to a transparent FBO
Render the lightmap to another FBO (using box2dLights)
Blend both products together using a custom shader
Draw the static background
Draw the blended texture from step 3
Draw the HUD
The problem I'm facing is that I obtain a white sprite when rendering background B (not a white block; it is more like a rgba(1, 1, 1, x). Then the background B is blended correctly with the lightmap (render step 3), but I cannot get its real color, just white:
The background B should appear dark blue and with a texture; it appears as a white sprite (blended with the lightmap). Behind background A, at the left of the picture (and also where the "SHADOW" text is), you can still see background B in a purplish tone, result of the blending with the light map, but please note it has no texture and it seems to me like if the texture is just plain white + alpha.
The render code:
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
/* 1. Update Physics and lights */
if (worldFixedStep(delta)) {
rayHandler.update();
}
updateCameras();
cameraMatrixCopy.set(camera.combined);
rayHandler.setCombinedMatrix(cameraMatrixCopy.scale(Globals.BOX_TO_WORLD, Globals.BOX_TO_WORLD, 1.0f), camera.position.x,
camera.position.y, camera.viewportWidth * camera.zoom * Globals.BOX_TO_WORLD,
camera.viewportHeight * camera.zoom * Globals.BOX_TO_WORLD);
rayHandler.render();
final Texture lightMap = rayHandler.getLightMapTexture();
fbo.begin();
{
Gdx.gl.glClearColor(0f, 0f, 0f, 0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
/* 2. Draw the backgrounds */
batch.enableBlending();
batch.setBlendFunction(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
batch.setProjectionMatrix(bgCamera2.combined); //Background B
batch.begin();
bTileMapRenderer.setView(bgCamera2);
bTileMapRenderer.renderTileLayer(tilesBg2Layer);
batch.end();
batch.setProjectionMatrix(bgCamera1.combined); //Background A
batch.begin();
bTileMapRenderer.setView(bgCamera1);
bTileMapRenderer.renderTileLayer(tilesBg1Layer);
batch.end();
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA); //FIXME this is where to touch to avoid gray alpha'ed borders.
batch.setProjectionMatrix(camera.combined);
batch.begin();
(...) //Draw everything else that needs to be blended with the light map
batch.end();
}
fbo.end();
/* 3. Render the static background (background C) */
batch.setProjectionMatrix(bgCameraStatic.combined);
batch.disableBlending();
batch.begin();
bTileMapRenderer.setView(bgCameraStatic);
bTileMapRenderer.renderTileLayer(tilesBg3Layer);
batch.end();
/* 4. Blend the frame buffer's texture with the light map in a fancy way */
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);
fboRegion.getTexture().bind();
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE1);
lightMap.bind();
Gdx.gl20.glEnable(Gdx.gl20.GL_BLEND);
Gdx.gl20.glBlendFunc(Gdx.gl20.GL_SRC_ALPHA, Gdx.gl20.GL_ONE_MINUS_SRC_ALPHA);
lightShader.begin();
lightShader.setUniformf("ambient_color", bgColor[0], bgColor[1], bgColor[2]);
lightShader.setUniformi("u_texture0", 0);
lightShader.setUniformi("u_texture1", 1);
fullScreenQuad.render(lightShader, GL20.GL_TRIANGLE_FAN, 0, 4);
lightShader.end();
Gdx.gl20.glDisable(Gdx.gl20.GL_BLEND);
hud.draw();
}
I just can't understand why this background is drawn white but still with its alpha data. The image is a premultiplied alpha texture, but again I cannot see why could this affect the color rendering.
Any help would be much appreciated.
Cheers
In a minecraft-like game I'm making, I'm getting these weird lines on polygon edges:
I'm using a texture atlas, being clamped with GL_CLAMP_TO_EDGE.
I tried using setting GL_TEXTURE_MIN_FILTER to GL_LINEAR, GL_NEAREST and even using mipmaps, but it doesn't make a difference. I also tried insetting the texture coordinates by half a pixel, or using x16 anisotropic filtering, with no sucess.
Any help?
Edit - The top face of the cubes is being rendered something like this:
glBegin(GL_QUADS);
glTexCoord2f(0f, 0f);
glVertex3f(x, y + 1f, z);
glTexCoord2f(0f, 1 / 8f);
glVertex3f(x, y + 1f, z + 1f);
glTexCoord2f(1 / 8f, 1 / 8f);
glVertex3f(x + 1f, y + 1f, z + 1f);
glTexCoord2f(1 / 8f, 0f);
glVertex3f(x + 1f, y + 1f, z);
glEnd();
This looks like the classical texture pixel <-> screen pixel fenceposting problem to me. See my answer to it here: https://stackoverflow.com/a/5879551/524368
Another issue might be, that the corner coordinates of the cubes are not exactly the same. Floating point numbers have some intrinsic error and if you arrange those cubes in a grid by adding some floating point number to it, it may happen, that the vertex positions get slightly off and due to roundoff error you get to see depth fighting. Two things to solve this: 1st: If two cubes' faces touch, don't render them. 2nd: Use integer coordinates for laying out the cube grid and convert the vertices to floating point only when submitting to OpenGL, or don't convert at all.
Making a 2D OpenGL game. When rendering a frame I need to first draw some computed quads geometry and then draw some textured sprites. When the body of my render method only draws the sprites, everything works fine. However, when I try to draw my geometric quads prior to the sprites the texture of the sprite changes to be the color of the last GL.Color3 used previously. How do I tell OpenGL (well, OpenTK) "Ok, we are done drawing geometry and its time to move on to sprites?"
Here is what the render code looks like:
// Let's do some geometry
GL.Begin(BeginMode.Quads);
GL.Color3(_dashboardBGColor); // commenting this out makes my sprites look right
int shakeBuffer = 100;
GL.Vertex2(0 - shakeBuffer, _view.DashboardHeightPixels);
GL.Vertex2(_view.WidthPixelsCount + shakeBuffer, _view.DashboardHeightPixels);
GL.Vertex2(_view.WidthPixelsCount + shakeBuffer, 0 - shakeBuffer);
GL.Vertex2(0 - shakeBuffer, 0 - shakeBuffer);
GL.End();
// lets do some sprites
GL.Begin(BeginMode.Quads);
GL.BindTexture(TextureTarget.Texture2D, _rockTextureId);
float baseX = 200;
float baseY = 200;
GL.TexCoord2(0, 0); GL.Vertex2(baseX, baseY);
GL.TexCoord2(1, 0); GL.Vertex2(baseX + _rockTextureWidth, baseY);
GL.TexCoord2(1, 1); GL.Vertex2(baseX + _rockTextureWidth, baseY - _rockTextureHeight);
GL.TexCoord2(0, 1); GL.Vertex2(baseX, baseY - _rockTextureHeight);
GL.End();
GL.Flush();
SwapBuffers();
The default texture environment mode is GL_MODULATE, which does that, it multiplies the texture color with the vertex color.
A easy solution is to set the vertex color before drawing a textured primitive to 1,1,1,1 with:
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
Another solution is to change the texture environment mode to GL_REPLACE, which makes the texture color replace the vertex color and doesn't have the issue:
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);