My image disappears if I add Opengl transformations.
void renderFileButton()
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glViewport(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 320, 0, 240, -1, 1);
glMatrixMode(GL_MODELVIEW);
glGenBuffers(1, &vertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(file_vertices), file_vertices,
GL_STATIC_DRAW);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(fileButtonVertexData), (GLvoid *)
offsetof(fileButtonVertexData, fileButtonPositionCoordinates));
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(fileButtonVertexData), (GLvoid *)
offsetof(fileButtonVertexData, fileButtonTextureCoordinates));
loadsprite("files/sprites/options.png");
glScalef(0, 0, 1);
glRotatef(180, 1, 0, 0);
glTranslatef(0, 0, 0);
glPopMatrix();
}
Could someone tell me where I'm in the wrong here?
You've scaled by zero. That makes the object's size zero. No surprise that it disappears.
In the future, you can troubleshoot by adding one transformation at a time, and trying to add a transformation that doesn't do anything (scale by 1, rotate by 0, translate by 0). Then increase the transformation slowly until you get to your intended value.
Also, your glPopMatrix is undoing all your transformations.
Finally, I don't see any actual rendering. Just a lot of state manipulation.
I found the problem after playing with it all last night. The transformation order was the issue.
glTranslatef(100, 100, 0);
glRotatef(180.0f,0.0f,0.0f,1.0f);
glScalef(-1.0f,1.0f,1.0f);
This does the job, that is all.
Related
I have been attempting to transition my game's prototype renderer from it's immediate mode testing implementation to an actual VAO/VBO implementation. The VBO is rendering on screen, but is refusing to texture. Below is the simplest test class that shows the problem:
public static void main(String[] args) throws Exception {
// VertX,VertY TexX, TexY
float[] data = new float[] {0.0f, 0.0f, 0.25f, 0.75f,
0.0f, 64.0f, 0.25f, 1.0f,
64.0f, 64.0f, 0.5f, 1.0f,
0.0f, 0.0f, 0.25f, 0.75f,
64.0f, 64.0f, 0.5f, 1.0f,
64.0f, 0.0f, 0.5f, 0.75f};
glfwSetErrorCallback(GLFWErrorCallback.createPrint(System.err));
if (!glfwInit())
throw new IllegalStateException("Unable to initialize GLFW");
long window = GLFW.glfwCreateWindow(1600, 900, "TEST", 0, 0);
GLFW.glfwMakeContextCurrent(window);
GL.createCapabilities();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1600, 900, 0, 0.000001, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
int vboId = glGenBuffers();
int vaoId = glGenVertexArrays();
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindVertexArray(vaoId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 4*Float.BYTES, 0);
glTexCoordPointer(2, GL_FLOAT, 4*Float.BYTES, 4*Float.BYTES);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glTranslatef(50, 50, 0);
Texture t = new Texture(TEST.class.getClassLoader().getResourceAsStream("test/WallFloor.png"));
while (!GLFW.glfwWindowShouldClose(window)) {
GLFW.glfwPollEvents();
GLFW.glfwSwapBuffers(window);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindVertexArray(vaoId);
glEnableVertexAttribArray(0);
t.bind();
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
/* Equivelent immediate mode code - that works
t.bind();
glBegin(GL_TRIANGLES);
glTexCoord2f(0.25f, 0.75f);
glVertex2f(0, 0);
glTexCoord2f(0.25f, 1f);
glVertex2f(0, 64);
glTexCoord2f(0.5f, 0.75f);
glVertex2f(64, 0);
glTexCoord2f(0.5f, 1f);
glVertex2f(64, 64);
glTexCoord2f(0.25f, 1f);
glVertex2f(0, 64);
glTexCoord2f(0.5f, 0.75f);
glVertex2f(64, 0);
glEnd();
*/
}
}
The texture bind call is the following (where wrap = GL_REPEAT and filter = GL_NEAREST):
public void bind()
{
glActiveTexture(GL_TEXTURE0);
glClientActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(target, id);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);
}
Having spent the weekend googling it an not finding an answer, am I doing something horribly wrong? I have also tested using immediate mode, which does still render with a texture.
In addition, you are mixing core profile code (glVertexAttribPointer) with non-core profile (glTexCoordPointer)
But the real problem comes from the wrong stride and offset used. Stride defines how large the data of one vertex is, while the offset specifies how far from the beginning of each vertex the actual data starts. In your case, every vertex consists of 4 floats thus the stride has to be 4 * Float.BYTES. The positions are the first two floats in each vertex (offset 0) while the texture coordinates are the 3rd and 4th floats which means offset = 2 * Float.BYTES. The correct code could look somehow like this (note the usage of glVertexPointer instead of glVertexAttribPointer):
glVertexPointer(2, GL_FLOAT, false, 4*Float.BYTES, 0);
glTexCoordPointer(2, GL_FLOAT, 4*Float.BYTES, 2*Float.BYTES);
Edit
The usage of your VAOs is also wrong. In the initialization you store the glVertexPointer/glTexCoordPointer to the VAO vaoId. But in the rendering code you bind VAO 0 instead. Most probably the attribute settings are not present when drawing. In addition, I'm not absolutely sure whether VAOs work together with fixed function calls. In this case you can remove all of the VAO calls.
How do I transform previously drawn elements? I've drawn a rough 4 million vertices to the screen, and I'd like to translate them after they are drawn. I'd prefer not to redraw them each time I want to translate them (4 million!)
Here is the relevant code.
glOrtho(0, 1024, 0, 576, 0, -4096);
glTranslatef(-512, -288, 512);
glRotatef(45, 1, 0, 0);
glTranslatef(512, 0, -512);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.F, 1.F, 1.F);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_INT, 0, &vertices[0]);
glDrawElements(GL_QUADS, vertexIndex.size(), GL_UNSIGNED_INT, &vertexIndex[0]);
glDisableClientState(GL_VERTEX_ARRAY);
// I would like to translate here
It is not possible, your vertex positions are internally multiplied with a transformation matrix to get the final position which is drawn on the screen.
So if you try to change the matrix after drawing it doesn't have any effect on the drawn vertices, and its goo that way.
To solve your problem just transform it before drawing... its the standard way, there is no other way to do it.
I've been trying to render a cube in a QGLWidget, but it comes out wrong. No matter how I rotate it, it looks like a flat square. It's like it didn't notice the Z coordinates of its vertices. Just before I added clearing of the GL_DEPTH_BUFFER_BIT, the square looked like all of the cube's sides crammed into one. Now it seems to discard vertices which don't belong in the front side, but it still isn't a cube.!
Screenshots [link]
My initializeGL() and paintGL():
typedef struct
{
float XYZW[4];
float RGBA[4];
} Vertex;
Vertex Vertices[8] =
{
//vertices
};
const GLubyte Indices[36] =
{
//indices
};
void ModelView::initializeGL()
{
m_program = new QGLShaderProgram(this);
m_program->addShaderFromSourceCode(QGLShader::Vertex, vertexShaderSource);
m_program->addShaderFromSourceCode(QGLShader::Fragment, fragmentShaderSource);
m_program->link();
}
void ModelView::paintGL()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearColor(.5f, .5f, .5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, width(), height());
m_program->bind();
QMatrix4x4 matrix;
matrix.perspective(60, 4.0/3.0, 0.1, 100.0);
matrix.translate(0, 0, -2);
matrix.rotate(50.0, 1, 1, 1);
m_program->setUniformValue(m_matrixUniform, matrix);
m_posAttr = m_program->attributeLocation("posAttr");
m_colAttr = m_program->attributeLocation("colAttr");
m_matrixUniform = m_program->uniformLocation("matrix");
glGenBuffers(1, &BufferId);
glGenBuffers(1, &IndexBufferId);
glBindBuffer(GL_ARRAY_BUFFER, BufferId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId);
glBufferData(GL_ARRAY_BUFFER, BufferSize, Vertices, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, VertexSize, 0);
glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, VertexSize, (GLvoid *)RgbOffset);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, NULL);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
m_program->release();
}
Vertices and Indices should be defined correctly, they're taken from a tutorial, as is most of the code. Rendering of 2D object seems to be just fine, though.
Also, why does the tutorial call matrix.translate with the -2 argument? If I change it to anything else greater than 1 or remove it, the rendered object disappears.
Qt5, Windows Vista 32-bit.
Also, why does the tutorial call matrix.translate with the -2
argument? If I change it to anything else greater than 1 or remove it,
the rendered object disappears.
This is due to clipping. When you render objects, things that are "too close" or "too far" are discarded, via the near and far clipping planes (respectively).
By moving the cube closer (changing -2 to 1 or 0), you are bringing the cube forward, past the near clipping plane, and it consequently disappears.
glVertexAttribPointer() has a size parameter, which specifies the number of components per vertex. In the code it is 2, therefore everything is 2D. Changing to 3 solves the issue.
As you can see from the images below, I have two triangles side by side (viewed from front). But when I view it from the right, the yellow triangle shows as if it is in front of the green triangle where it should not be visible because it is behind the green one (see right view), why is this happening? Viewing it from the left is fine (see left view). Thanks.
FrontView:
Right View (why is the yellow triangle is still visible?):
Left view (viewing from here is fine):
This is my render method. Even though I don't use glColor4f and do the coloring in a modern way, I still have the same result. I have also set glEnable(GL_DEPTH); and
glDepthFunc(GL_LESS);
void display(){
glClear(GL_COLOR_BUFFER_BIT);
control(0.2, 0.2, mi);
view = updateCam();
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
model = glm::rotate(glm::mat4(1.0), 45, glm::vec3(0, 1, 0));
glColor4f(0, 1, 0, 1);
glDrawArrays(GL_TRIANGLES, 0, 3);
resetMatrix();
model = glm::translate(glm::mat4(1.0), glm::vec3(5, 0, 0));
model = glm::rotate(model, 45, glm::vec3(0, 1, 0));
glColor4f(1, 1, 0, 1);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
resetMatrix();
SDL_GL_SwapBuffers();
}
You're only clearing your color buffer. The depth buffer still contains the depth values from previous frames, so your Z-test doesn't work as intended.
Clear them both:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Simple question:
How does this piece of code
glBindTexture(GL_TEXTURE_2D, texture_);
glColor4f(1,1,1,1);
glBegin(GL_QUADS);
glTexCoord2f(0, 1); glVertex2f(left_, top_);
glTexCoord2f(1, 1); glVertex2f(right_, top_);
glTexCoord2f(1, 0); glVertex2f(right_, bottom_);
glTexCoord2f(0, 0); glVertex2f(left_, bottom_);
glEnd();
translate to modern OpenGL code with vertex arrays?
If you just want to port these lines to vertex arrays, it is as simple as:
static const float texCoords[8] = {
0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f };
float vertices[8] = {
left_, top_, right_, top_, right_, bottom_, left_, bottom_ };
glBindTexture(GL_TEXTURE_2D, texture_);
glColor4f(1,1,1,1);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_QUADS, 0, 4);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableCLientState(GL_VERTEX_ARRAY);
However, this has nothing to do with modern OpenGL, in fact this code is completely valid OpenGL 1.1 code. Modern OpenGL is not just about vertex arrays over immediate mode. It is also about storing vertex data in vertex buffer objects (VBOs) and doing every computation (like transformation, lighting, texturing, ...) with shaders instead of the old fixed-function pipeline. So really porting this to modern OpenGL is in fact not such a simple question.
Since your question suggests that you aren't aware of all this, it doesn't make much sense to explain it here, as it doesn't just come down to 5-10 lines of code that you only need to subsitute for the lines in the question. You should rather consult some serious learning resource on modern OpenGL if that is what you want to do.
If all you want to do is indeed to use vertex arrays instead of immediate mode, then the above code should be sufficient, though it won't really buy you anything in this example, I guess.
BindTexture wll stay... but the rest.
1 in init method create VBO for vertices. Those vertices should be:
float verts[4*(2+3)] = { 0, 1, left_, top_, 0,
1, 1, right_, top_, 0,
1, 0, right_, bottom_, 0,
0, 1, left_, bottom_, 0 };
2 copy verts to GPU (glBufferData)
3 use glVertexAttribPointer to set up buffer data with attribs
4 draw arrays
for instance
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, bufID);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float)*5, sizeof(float)*2);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float)*5, 0);
glDrawArrays with Triangle_strip