OpenGL Working with OGL3.x-

Recommended Posts

Hi!
I've been setting up a new context for some time now. And I finally seem to get to grips with it. However, I can't render anything in my window, which is quite crippling...

I'm loading an OBJ into vectors and load that information into a couple of VBO's for texccords, vertex position, normals and a vector for indices.
I know for a fact that the code I'm using is functional under lower contexts and I just can't get it to work in the new one.

I'm thinking that it's got something to do with using my own matrices and how the shaders are set up... but I can't figure it out.

My render function:
void cOpenGLContext::renderScene(void) {	glViewport(0, 0, windowWidth, windowHeight);	// set the viewport to fill the entire window	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);	// clear required buffers	viewMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -5.0f));		// create our view matrix which will translate us back 5 units	modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));// create our model matrix which will halve the size of our model	shader->bind();		int projectionMatrixLocation = glGetUniformLocation(shader->id(), "projectionMatrix");	// get the location of our projection matrix in the shader		int viewMatrixLocation = glGetUniformLocation(shader->id(), "viewMatrix");	// get the location of our view matrix in the shader		int modelMatrixLocation = glGetUniformLocation(shader->id(), "modelMatrix");	// get the location of our model matrix in the shader		glUniformMatrix4fv(projectionMatrixLocation, 1, GL_FALSE, &projectionMatrix[0][0]);// send our projection matrix to the shader		glUniformMatrix4fv(viewMatrixLocation, 1, GL_FALSE, &viewMatrix[0][0]);	// send our view matrix to the shader		glUniformMatrix4fv(modelMatrixLocation, 1, GL_FALSE, &modelMatrix[0][0]);	// send our model matrix to the shader		// rest of render function here		// VBO [start]		// drawing		glEnableClientState(GL_VERTEX_ARRAY);		glEnableClientState(GL_NORMAL_ARRAY);		glEnableClientState(GL_TEXTURE_COORD_ARRAY);			// vertex buffer			glBindBuffer(GL_ARRAY_BUFFER, earth.vBufferObject);			glVertexPointer(3, GL_FLOAT, 0, 0);			// texture buffer			glBindBuffer(GL_ARRAY_BUFFER, earth.tBufferObject);			glTexCoordPointer(3, GL_FLOAT, 0, 0);			// normal buffer			glBindBuffer(GL_ARRAY_BUFFER, earth.nBufferObject);			glNormalPointer(GL_FLOAT, 0, 0);			// index buffer			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, earth.iBufferObject);			// draws it all			glDrawElements(GL_TRIANGLES, earth.vFaces.size(), GL_UNSIGNED_INT, 0);			// unbinds the buffers			glBindBuffer(GL_ARRAY_BUFFER, 0);			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);		glDisableClientState(GL_TEXTURE_COORD_ARRAY);		glDisableClientState(GL_NORMAL_ARRAY);		glDisableClientState(GL_VERTEX_ARRAY);		// drawing end	shader->unbind();	SwapBuffers(hdc);																// swap buffers so we can see our rendering}

// vert#version 150 corein vec3 in_Position;in vec3 in_Color;out vec3 pass_Color;uniform mat4 projectionMatrix;uniform mat4 viewMatrix;uniform mat4 modelMatrix;void main(void) {	gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_Position, 1.0);	pass_Color = in_Color;}// frag#version 150 corein vec3 pass_Color;out vec4 out_Color;void main(void) {	out_Color = vec4(pass_Color, 1.0);}

Can anyone see what I'm doing wrong? I'm going blind, staring at this code.

Thanks!
Marcus

Share on other sites
It looks like you need to study the 3.x specification a bit more closely. OpenGL 3 deprecates a lot of functionality. Just skimming over your code, I can see lots of deprecated code: glEnableClientState, glVertexPointer, etc. You need to learn how to use vertex attribute arrays.

If you are running OpenGL 3.2 or later, those functions simply will not work at all. Running 3.1 should enable that deprecated functionality.

Share on other sites
Hi, TheBuzzSaw.
Do you mean something like:

// function for setting up the buffersglGenBuffers(1, &vBufferObject);glBindBuffer(GL_ARRAY_BUFFER, vBufferObject);glBufferData(GL_ARRAY_BUFFER, ((int)(vertices.size()) * 3 * sizeof(float)), &(vertices.at(0)), GL_STATIC_DRAW);glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);// ...// draw functionglBindVertexArray(earth.vBufferObject);glDrawArrays(GL_TRIANGLES, 0, 3);

Share on other sites
Yes, you are on the right track. I've not gotten into the habit of using vertex array objects yet, but vertex attribute arrays and vertex buffer objects should pretty much drive your entire program. ;)

Share on other sites
Hm hm. Okay. I've got stuff to think about then. Crap. But thanks for your answer :)

Thanks!
Marcus

Share on other sites
Here's how I use VAO and VBO: Cube.cpp

Share on other sites
Quote:
 Original post by TrefallHere's how I use VAO and VBO: Cube.cpp

Thanks for posting that. That's how I'm doing it right now. But I'm still not getting anything on the screen. Just my regular background.

// vao, vbo, ibo setupvao = 0;// vertex bufferglGenVertexArrays(1, &vao);glBindVertexArray(vao);glGenBuffers(1, &vBufferObject);glBindBuffer(GL_ARRAY_BUFFER, vBufferObject);glBufferData(GL_ARRAY_BUFFER, sizeof(float)*vertices.size(), NULL, GL_STATIC_DRAW);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*vertices.size(), &vertices[0]);//.....// render functionglBindVertexArray(earth.vao);glDrawElements(GL_TRIANGLES, earth.vFaces.size(), GL_UNSIGNED_INT, 0);glBindVertexArray(0);

Thanks for the help, guys.

Share on other sites
I assume you also bind and buffer your index list? :) Use this snippet to see if OpenGL is throwing any errors internally:

{  GLenum err = glGetError();  if(err != GL_NO_ERROR)    std::cout << "OpenGL prog error: " << gluErrorString(err) << std::endl;  std::cout.flush();}

Share on other sites
You don't wanna be using GLU in OpenGL 3.

I would recommend trying to draw without VAOs for testing. Just see if you can bind a buffer and draw it.

Share on other sites
You also may want to calculate your modelview * projection matrix on the CPU and uploading it once to the GPU instead of doing it per-vertex. The model matrix has to be passed up separately for each unique object. The only access you have to the GL default attributes is to the gl_* attributes in your shader. User defined attributes have to be bound and specified by the user...it doesn't happen automagically. See the GLSL spec for reference. With that said your shader is transforming some unknown attributes since the default vertex attribute that is bound to glVertexPointer is gl_Vertex which is not valid when version 150 is define.

Share on other sites
Ah yes. I definitely agree. Do as much of the work on the CPU as you can. If you know that the work needs to be done once, and it affects all the vertices you are about to draw, forcing every vertex to do the same work is wasteful.

Share on other sites
Quote:
 Original post by cgrantYou also may want to calculate your modelview * projection matrix on the CPU and uploading it once to the GPU instead of doing it per-vertex. The model matrix has to be passed up separately for each unique object. The only access you have to the GL default attributes is to the gl_* attributes in your shader. User defined attributes have to be bound and specified by the user...it doesn't happen automagically. See the GLSL spec for reference. With that said your shader is transforming some unknown attributes since the default vertex attribute that is bound to glVertexPointer is gl_Vertex which is not valid when version 150 is define.

Allright, seems like I've got quite a bit to rework, then.
- Calculate modelview * projection matrix on the CPU and upload it to the GPU once for each unique object
- Since I'm using GLSL version 150 I need some other way to point to my vertices.

Taking another look at the GLSL and OpenGL specifications.

Thanks!

Share on other sites
Quote:
 Original post by TheBuzzSawYou don't wanna be using GLU in OpenGL 3.

You should correct that comment to: "you don't want to use GLU functionality that use deprecated OpenGL functionality" ;) gluErrorString is perfectly safe to use with OpenGL 3.x, and is quite convenient actually. Of course, you could always make your own string registry on GL error enums.

Quote:
 Original post by tre- Since I'm using GLSL version 150 I need some other way to point to my vertices.

Just send them in as attributes, with a buffer offset towards your VBO. Since you only have vertices in the vbo, that means you will point to the first element of your vbo. OpenGL will handle the rest for you :) If you refer back to my Cube.cpp you'll see how I've handled this.

#ifndef BUFFER_OFFSET        #define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + bytes)#endifstatic void shaderAttrib(unsigned int prog, const char *attribName, int size, GLenum type, bool normalized, int stride, void* pointer){        int id = glGetAttribLocation(prog, attribName);        if(id < 0)                throw CL_Exception(cl_format("Failed to load attribute %1", attribName));                        glVertexAttribPointer(id, size, type, normalized, stride, pointer);        glEnableVertexAttribArray(id);}//usage:shaderAttrib(shader.getShaderProg(), "vVertex", 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));

Just make sure you use it while the VAO/VBO is still bound.

Share on other sites
Quote:
 Original post by treAllright, seems like I've got quite a bit to rework, then.- Calculate modelview * projection matrix on the CPU and upload it to the GPU once for each unique object- Since I'm using GLSL version 150 I need some other way to point to my vertices.Taking another look at the GLSL and OpenGL specifications.Thanks!

Don't be afraid to transmit several matrices into the shaders either. For instance, some shader designs require access to just the model view or just the projection. However, you still don't want every single vertex doing unnecessary matrix math, so it is still smart to transmit the pre-multiplied model view projection matrix. One of my shaders, for instance, has uniform matrices "MVPM", "MVM", and "PM".

Quote:
 Original post by TrefallYou should correct that comment to: "you don't want to use GLU functionality that use deprecated OpenGL functionality" ;) gluErrorString is perfectly safe to use with OpenGL 3.x, and is quite convenient actually. Of course, you could always make your own string registry on GL error enums.

Fair enough. The only stuff I was using from GLU back in the day was gluPerspective and gluUnProject. I just looked up how they were both calculated and rid myself my GLU entirely. It's also an annoying extra dependency in projects. XD

Share on other sites
Allright. After some time I've got my program up and running with drawing happening.
The problem I'm facing now is that my model is not being drawn correctly. I've had this problem before and I think I know the cause - reading in an OBJ-file and only drawing the vertices messes it up when trying to draw anything else than GL_POINTS.
However, I don't know of any way to draw using face indices instead of the raw vertex data, using VAO's and VBO's.

The way I'm setting up my VAO+VBO:
// vertex bufferglGenVertexArrays(1, &vao);glBindVertexArray(vao);glGenBuffers(1, &vBufferObject);glBindBuffer(GL_ARRAY_BUFFER, vBufferObject);glBufferData(GL_ARRAY_BUFFER, sizeof(float)*vertices.size(), NULL, GL_STATIC_DRAW);glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float)*vertices.size(), &vertices[0]);

So, that's setting up my VAO+VBO using a vertex array. I'll have to change this so that the program reads and loads the indices. How?

Then the rendering part:
...glBindVertexArray(vaoID[0]);glDrawArrays(GL_TRIANGLE_STRIP, 0, earth.vertices.size());glBindVertexArray(0);...

How does this have to change to draw the model using the face indices? I just can't seem to find any good information on drawing using those instead. Maybe I'm stupid, but I just can't.

If anyone would like to explain it to me or point me in the right direction, it'd be great.

Thanks again, guys!
Marcus

Share on other sites
If you are trying to draw OBJ data, where are your indices? Look into using glDrawElements.

Share on other sites
Quote:
 Original post by TheBuzzSawIf you are trying to draw OBJ data, where are your indices? Look into using glDrawElements.

My indices are loaded when the model is loaded and set up last of the buffers for vertices, texture coordinates and normals.

Here:
// index bufferglGenBuffers(1, &iBufferObject);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iBufferObject);glBufferData(GL_ELEMENT_ARRAY_BUFFER, ((int)(vFaces.size()) * 3 * sizeof(float)), &(vFaces.at(0)), GL_STATIC_DRAW);

I were looking at glDrawElements... at the moment I'm loading all my vertex information from a Vertex Array Object. How is the process when using the indices? The same? As I understand it a VBO can be loaded with any information (vertex, normal, elements, texture coordinates) and a VAO can be loaded with several VBO's.

Share on other sites
VBOs hold any sort of data in OpenGL, VAOs hold OpenGL state that should be applied for a single rendering call.

VAOs are there just for convenience, so you wont need to bind your buffers and make the pointers every single time you want to draw with your buffers.

Now, you can have as many (or there's probably a limit you will never get to) VBOs holding vertex data (GL_ARRAY_BUFFER) in a VAO, and one indices VBO (GL_ELEMENT_ARRAY_BUFFER).
If the VAO has an indices buffer, you can then use any rendering functions that use indices, glDraw*Elements*.

Here's a very good site teaching OpenGL 3.3 http://www.arcsynthesis.org/gltut/index.html

Create an account

Register a new account

• Partner Spotlight

• Forum Statistics

• Total Topics
627684
• Total Posts
2978627
• Similar Content

• Both functions are available since 3.0, and I'm currently using glMapBuffer(), which works fine.
But, I was wondering if anyone has experienced advantage in using glMapBufferRange(), which allows to specify the range of the mapped buffer. Could this be only a safety measure or does it improve performance?
Note: I'm not asking about glBufferSubData()/glBufferData. Those two are irrelevant in this case.
• By xhcao
Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness.
• By cebugdev
hi guys,
are there any books, link online or any other resources that discusses on how to build special effects such as magic, lightning, etc. in OpenGL? i mean, yeah most of them are using particles but im looking for resources specifically on how to manipulate the particles to look like an effect that can be use for games,. i did fire particle before, and I want to learn how to do the other 'magic' as well.
Like are there one book or link(cant find in google) that atleast featured how to make different particle effects in OpenGL (or DirectX)? If there is no one stop shop for it, maybe ill just look for some tips on how to make a particle engine that is flexible enough to enable me to design different effects/magic
let me know if you guys have recommendations.
• By dud3
How do we rotate the camera around x axis 360 degrees, without having the strange effect as in my video below?
Mine behaves exactly the same way spherical coordinates would, I'm using euler angles.
Tried googling, but couldn't find a proper answer, guessing I don't know what exactly to google for, googled 'rotate 360 around x axis', got no proper answers.

References:
Code: https://pastebin.com/Hcshj3FQ
The video shows the difference between blender and my rotation:

• By Defend
I've had a Google around for this but haven't yet found some solid advice. There is a lot of "it depends", but I'm not sure on what.
My question is what's a good rule of thumb to follow when it comes to creating/using VBOs & VAOs? As in, when should I use multiple or when should I not? My understanding so far is that if I need a new VBO, then I need a new VAO. So when it comes to rendering multiple objects I can either:
* make lots of VAO/VBO pairs and flip through them to render different objects, or
* make one big VBO and jump around its memory to render different objects.
I also understand that if I need to render objects with different vertex attributes, then a new VAO is necessary in this case.
If that "it depends" really is quite variable, what's best for a beginner with OpenGL, assuming that better approaches can be learnt later with better understanding?

• 9
• 14
• 12
• 10
• 12