I'm developing a 2D game called Spaceland and I've ran into a problem with clearing the screen. Whenever I call glClear(GL_COLOR_BUFFER_BIT) every frame, it keeps my screen black until i stop calling it. I have tested this by assigning glClear() to a key, and when I hold it down the screen turns black, when not pressed, the quad that is spreading across the screen just grows until I clear again.
I am using glClearColor(0, 0, 0, 1) when I create a window. I have tried turning off and on glfwSwapInterval().
create() function in my Window class:
public void create(boolean vsync) {
GLFWErrorCallback.createPrint(System.err).set();
GLFWVidMode vid = glfwGetVideoMode(glfwGetPrimaryMonitor());
keys = new boolean[GLFW_KEY_LAST];
for (int i = 0; i < GLFW_KEY_LAST; i ++) {
keys[i] = false;
}
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
ID = glfwCreateWindow(vid.width(), vid.height(), TITLE, glfwGetPrimaryMonitor(), 0);
if (ID == 0)
throw new IllegalStateException("Error whilst creating window: '" + TITLE + "'");
glfwMakeContextCurrent(ID);
createCapabilities();
glClearColor(0, 0, 0, 1);
camera = new Camera(getWidth(), getHeight());
glfwSwapInterval(vsync ? 1 : 0);
}
Sprite Class:
public class Sprite {
private VertexArray vao;
private VertexBuffer
pVbo,
iVbo;
private int vertexCount;
private float scale;
private Vector3f position;
private Vector3f rotation;
private Matrix4f tMatrix;
public Sprite(float[] pos, int[] indices) {
vertexCount = indices.length;
position = new Vector3f(0, 0, 0);
rotation = new Vector3f(0, 0, 0);
scale = 0.1f;
tMatrix = MatrixHelper.createTransformationMatrix(position, rotation, scale);
vao = new VertexArray();
pVbo = new VertexBuffer(false);
iVbo = new VertexBuffer(true);
vao.bind();
pVbo.bind();
pVbo.add(pos);
vao.add();
pVbo.unbind();
iVbo.bind();
iVbo.add(indices);
iVbo.unbind();
vao.unbind();
}
public void setPosition(float x, float y, float z) {
position.x = x;
position.y = y;
position.z = z;
}
public void setRotation(Vector3f rot) {
rotation = rot;
}
public void render(int renderType) {
MatrixHelper.setTMatrixPosition(tMatrix, position);
setPosition(getPosition().x + 0.0001f, 0, 0);
System.out.println(tMatrix);
Spaceland.shader.bind();
Spaceland.shader.editValue("transformation", tMatrix);
vao.bind();
glEnableVertexAttribArray(0);
iVbo.bind();
glDrawElements(renderType, vertexCount, GL_UNSIGNED_INT, 0);
iVbo.unbind();
glDisableVertexAttribArray(0);
vao.unbind();
Spaceland.shader.unbind();
}
public Vector3f getPosition() {
return position;
}
}
I don't think you need to see my Camera class or MatrixHelper class as the problem has occured before implementing this.
Main class (ignore rose[] and roseI[] it's just a cool pattern I made as a test):
public class Spaceland {
public static Window window;
public static Sprite sprite;
public static Shader shader;
public static float[] rose = {
-0.45f, 0f,
0.45f, 0f,
0f, 0.45f,
0f, -0.45f,
-0.4f, -0.2f,
-0.4f, 0.2f,
0.4f, -0.2f,
0.4f, 0.2f,
-0.2f, -0.4f,
-0.2f, 0.4f,
0.2f, -0.4f,
0.2f, 0.4f
};
public static int[] roseI = {
0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9, 0, 10, 0, 11,
1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 1, 10, 1, 11,
2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 2, 8, 2, 9, 2, 10, 2, 11,
3, 4, 3, 5, 3, 6, 3, 7, 3, 8, 3, 9, 3, 10, 3, 11,
4, 5, 4, 6, 4, 7, 4, 8, 4, 9, 4, 10, 4, 11,
5, 6, 5, 7, 5, 8, 5, 9, 5, 10, 5, 11,
6, 7, 6, 8, 6, 9, 6, 10, 6, 11,
7, 8, 7, 9, 7, 10, 7, 11,
8, 9, 8, 10, 8, 11,
9, 10, 9, 11,
10, 11,
};
public static float[] quad = {
0.5f, 0.5f,
0.5f, -0.5f,
-0.5f, 0.5f,
-0.5f, -0.5f
};
public static int[] quadI = {
2, 0, 3,
0, 1, 3
};
public static void main(String[] args) {
init();
}
public static void loop() {
while (!window.isCloseRequested()) {
update();
render();
}
destroy(0);
}
public static void init() {
if (!glfwInit())
throw new IllegalStateException("Error whilst initialising GLFW");
window = new Window("Spaceland");
window.create(true);
shader = new Shader("src/main/java/com/spaceland/graphics/fragment.fs", "src/main/java/com/spaceland/graphics/vertex.vs");
sprite = new Sprite(quad, quadI);
loop();
}
public static void render() {
window.render();
sprite.render(GL11.GL_TRIANGLES);
}
public static void update() {
window.update();
if (window.isDown(GLFW_KEY_SPACE)) {
glClear(GL_COLOR_BUFFER_BIT);
}
}
public static void destroy(int error) {
window.destroy();
glfwTerminate();
glfwSetErrorCallback(null).free();
shader.destroy();
VertexBuffer.deleteAll();
VertexArray.destroyAll();
System.exit(error);
}
}
Please tell me if you need to see the Shader class, shader vs and fs files, or anything else.
Thanks!
glClear affects the output buffers. So it is part of rendering. If you want to clear as part of your rendering, put glClear inside your render function.
You have it inside update. I suspect that whomever is calling render and update (LWJGL, presumably?) doesn't guarantee any particular ordering to them. So each time you're asked to update you're stomping on top of the last thing you rendered.
Updates:
adjust internal state, usually partly as a function of time.
Renders:
capture current state visually.
It is not very clear in my question, but the answer is that I cleared the screen, swapped buffers, rendered, etc. Which doesn't work.
glClear(...);
glfwSwapBuffers(...);
...render...
This is how it is currently, and this doesn't work.
glClear(...);
...render...
glfwSwapBuffers(...);
This is how I do it now, and it works fine.
Related
i created bezier surface in OpenGL this way:
GLfloat punktyWSP[5][5][3] = {
{ {0,0,4}, {1,0,4},{2,0,4},{3,0,4},{4,1,4}},
{ {0,0,3}, {1,1,3},{2,1,3},{3,1,3},{4,1,3} },
{ {0,1,2}, {1,2,2},{2,6,2},{3,2,2},{4,1,2} },
{ {0,0,1}, {1,1,1},{2,1,1},{3,1,1},{4,1,1} },
{ {0,0,0}, {1,0,0},{2,0,0},{3,0,0},{4,1,0} }
};
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 5, 0, 1, 15, 5, &punktyWSP[0][0][0]);
glEnable(GL_MAP2_VERTEX_3);
glMapGrid2f(u, 0, 1, v, 0, 1);
glShadeModel(GL_FLAT);
glEnable (GL_AUTO_NORMAL);
glEvalMesh2(GL_FILL, 0, u, 0, v);
Now i want to texture it.
Is there any way to add auto texture coordinates to my surface as it it with norms and glenable(gl_auto_normal)?
If there is no such a function, do you have any idea how to add coordinates to my surface? Maybe glEnable(GL_MAP2_TEXTURE_COORD_2) ?
I have this header (with hidden code):
class DrawBuffers
{
public:
struct CubeCorners
{
GLfloat corners[NUM_VERTS * ELEM_PER_NORM];
CubeCorners(bool normalize);
};
static const CubeCorners POSITIONS;
static const GLfloat COLOR_DEFAULT[ELEM_PER_COLOR];
static const CubeCorners NORMALS;
static const GLuint INDICES[NUM_INDICES / NB_FACES][NB_INDICES_PER_FACE];
};
I have this in the cpp:
const DrawBuffers::CubeCorners POSITIONS = DrawBuffers::CubeCorners(false);
const GLfloat DrawBuffers::COLOR_DEFAULT[] = {1.f, 1.f, 1.f, 1.f};
const DrawBuffers::CubeCorners NORMALS = DrawBuffers::CubeCorners(true);
const GLuint DrawBuffers::INDICES[][NB_INDICES_PER_FACE] = { //second indices
{0, 1, 2, // Back
2, 3, 0},
{7, 6, 5, // Front
5, 4, 7},
{4, 5, 1, // Left
1, 0, 4},
{3, 2, 6, // Right
6, 7, 3},
{4, 0, 3, // Bottom
3, 7, 4},
{6, 2, 1, // Top
1, 5, 6}};
And I still get an undefined reference to POSITIONS in the same .cpp file... Anything I may have forgotten?
Thank you! :)
These are static members, so you need to qualify the names in their definitions (as you've already done with two of them):
const DrawBuffers::CubeCorners DrawBuffers::POSITIONS = DrawBuffers::CubeCorners(false);
^^^^^^^^^^^^^
You've instead declared static non-member variables.
I'm trying to draw an Isocahedron in OpenGL with c++. I keep getting close but having some missing faces. I have found 3 different sets of vertex/index data on multiple sites, most often the data listed below
float X = 0.525731112119133606f;
float Z = 0.850650808352039932f;
float temppts[12][3] = { { -X, 0.0f, Z }, { X, 0.0f, Z }, { -X, 0.0f, -Z }, { X, 0.0f, -Z },
{ 0.0f, Z, X }, { 0.0f, Z, -X }, { 0.0f, -Z, X }, { 0.0f, -Z, -X },
{ Z, X, 0.0f }, { -Z, X, 0.0f }, { Z, -X, 0.0f }, { -Z, -X, 0.0f } };
GLushort tempindicies[60] =
{ 1, 4, 0, 4, 9, 0, 4, 5, 9, 8, 5, 4, 1, 8, 4,
1, 10, 8, 10, 3, 8, 8, 3, 5, 3, 2, 5, 3, 7, 2,
3, 10, 7, 10, 6, 7, 6, 11, 7, 6, 0, 11, 6, 1, 0,
10, 1, 6, 11, 0, 9, 2, 11, 9, 5, 2, 9, 11, 2, 7};
This code is adapted from a book and multiple sites display it working, though they are drawing immediate and I'm using vbo/ibo. Can anyone point me to some working vertex/index data or tell me what is going wrong transferring this to buffer objects? The three different data all have differently incorrect icosahedrons, each with different faces missing.
I have checked over my bufferData calls many times and tried several drawing modes ( TRIANGLES, TRIANGLE_STRIP ... ) and am convinced the index data is wrong somehow
I used the mesh coordinates (vertices) and the triangle connectivity from Platonic Solids (scroll down to icosahedron). I've pasted a screen shot from that file below. When calling glDrawElements I used GL_TRIANGLES.
Icosahedron
Another thing to watch out for is back face culling. Initially switch off backface culling.
glDisable(GL_CULL_FACE);
I'm working on what will eventually be a terrain drawer, however at the moment I am just trying to get a basic pair of triangles to draw with glDrawElements. The code looks as such:
public class TerrainFlat extends AbstractTerrain {
IntBuffer ib = BufferUtils.createIntBuffer(3);
int vHandle = ib.get(0);
int cHandle = ib.get(1);
int iHandle = ib.get(2);
FloatBuffer vBuffer = BufferUtils.createFloatBuffer(19);
FloatBuffer cBuffer = BufferUtils.createFloatBuffer(18);
ShortBuffer iBuffer = BufferUtils.createShortBuffer(6);
#Override
public void initilize(){
float[] vertexData = {50, 20, 100, 50, -20, 100, 10, -20, 100, -10, -20, 100, -50, -20, 100, -50, 20, 100};
float[] colorData = {1, 0, 0, 0, 1, 0, 0, 0, 1, 0 , 0 , 1 , 0 , 1 , 0 , 1 , 0 , 0 };
short[] indexData = {0,1,2,3,4,5};
vBuffer.put(vertexData);
vBuffer.flip();
cBuffer.put(colorData);
cBuffer.flip();
iBuffer.put(indexData);
iBuffer.flip();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iHandle);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, vBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cHandle);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, cBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
#Override
public void setUp(float posX, float posY, float posZ){
}
#Override
public void draw(){
glClear(GL_COLOR_BUFFER_BIT);
glGenBuffersARB(ib);
vHandle = ib.get(0);
cHandle = ib.get(1);
iHandle = ib.get(2);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle);
glVertexPointer(3, GL_FLOAT, 3 << 2 , 0L);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, cHandle);
glColorPointer(3, GL_FLOAT, 3 << 2 , 0L);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iHandle);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0L);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}
#Override
public void destroy(){
ib.put(0, vHandle);
ib.put(1, cHandle);
ib.put(2, iHandle);
glDeleteBuffersARB(ib);
}
}
This does not draw anything, the screen is entirely black. GL_CULL_FACE is not enabled, and there is no lighting (or lack thereof) to cause this error. Moving the data binding into the Draw() function lets it work (if you want I can add that code to this). This however means I create my buffer's every draw function (ie: bad). I'm wondering outright what I'm doing wrong here, because I've moved it around and slapped it silly for 4 days now.
You're setting vHandle, cHandle and iHandle to 0.
You never need to create the IntBuffer in line 1 anyway. Replace
int vHandle = ib.get(0);
int cHandle = ib.get(1);
int iHandle = ib.get(2);
with
int vHandle = glGenBuffers();
int cHandle = glGenBuffers();
int iHandle = glGenBuffers();
I want my class Vector3f to store index pointes for my cuboid (made from triangles).
Heres what I would push to the vector.
vector<Vector3f> I;
I.push_back(Vector3f(1, 0, 2)); //front
I.push_back(Vector3f(2, 0, 3));
I.push_back(Vector3f(4, 5, 7)); //back
I.push_back(Vector3f(7, 5, 6));
I.push_back(Vector3f(0, 4, 3)); //left
I.push_back(Vector3f(3, 4, 7));
I.push_back(Vector3f(5, 1, 6)); //right
I.push_back(Vector3f(6, 1, 2));
I.push_back(Vector3f(7, 6, 3)); //up
I.push_back(Vector3f(3, 6, 2));
I.push_back(Vector3f(1, 0, 5)); //down
I.push_back(Vector3f(5, 0, 4));
Can vertex arrays read from classes?
Assuming your Vector3f is POD
&I[0] will give your a float * which you can pass to glBufferData