OpenGL cube not showing, is it with near and far planes maybe?
-
28-06-2021 - |
Question
I cannot get my cube to show after trying to do a manual perspective transformation My code is below. I have a suspicion it maybe my near and far plane numbers.
-(void)drawRect:(NSRect)dirtyRect
{
// get the dimensions of the window
NSSize dim = [self frame].size;
// clear the background with color
glClearColor(0.0, 0.0, 0.0, 0.4);
glViewport(0, 0, dim.width, dim.height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// variables
GLfloat cubeHeight = 90.0;
GLfloat cubeWidth = 90.0;
GLfloat cubeLength = 200.0;
//GLfloat alpha = 0.0;
//GLfloat beta = 0.0;
//GLfloat gamma = 0.0;
// cube position data
GLfloat cubePositionData[] = {0.0, 0.0, 0.0,
0.0, 0.0, cubeLength,
cubeWidth, 0.0, cubeLength,
cubeWidth, 0.0, 0.0,
0.0, cubeHeight, 0.0,
0.0, cubeHeight, cubeLength,
cubeWidth, cubeHeight, cubeLength,
cubeWidth, cubeHeight, 0.0};
// cube indices data
GLubyte cubeIndices[] = {0, 1, 2, 0, 2, 3,
4, 5, 6, 4, 6, 7,
1, 2, 6, 1, 6, 5,
2, 3, 7, 2, 7, 6,
3, 0, 4, 3, 4, 7,
0, 1, 5, 0, 5, 4};
// cube color data
GLfloat cubeColorData[] = {0.0, 0.3, 0.8, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.3, 0.8, 1.0,
0.0, 0.3, 0.8, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
0.0, 0.3, 0.8, 1.0};
// array to hold buffer IDs
GLuint vertexBuffers[2];
// bind each array of data to separate buffers
// bind cube position data to the first buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubePositionData), cubePositionData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// bind the cube color data to the second buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeColorData), cubeColorData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// enable the shader program
GLuint programID = [self loadShaders];
glUseProgram(programID);
// enable vertex attributes
// enable cube position attributes
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[0]);
glEnableVertexAttribArray(VERTEX_POS_INDEX);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// enable cube color attributes
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffers[1]);
glEnableVertexAttribArray(VERTEX_COLOR_INDEX);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// point to the enabled attribute data
glVertexAttribPointer(VERTEX_POS_INDEX, VERTEX_POS_SIZE, GL_FLOAT, GL_FALSE, 0, cubePositionData);
glVertexAttribPointer(VERTEX_COLOR_INDEX, VERTEX_COLOR_SIZE, GL_FLOAT, GL_FALSE, 0, cubeColorData);
GLfloat offset[] = {0.5, 0.5};
GLint offsetUnif = glGetUniformLocation(programID, "offset");
GLint zNearUnif = glGetUniformLocation(programID, "zNear");
GLint zFarUnif = glGetUniformLocation(programID, "zFar");
GLint frustumScaleUnif = glGetUniformLocation(programID, "frustumScale");
glUniform2fv(offsetUnif, 1, offset);
glUniform1f(frustumScaleUnif, 1.0f);
glUniform1f(zNearUnif, 1.0);
glUniform1f(zFarUnif, 3.0);
// draw the elements
glDrawElements(GL_TRIANGLES, sizeof(cubeIndices)/sizeof(GLubyte), GL_UNSIGNED_BYTE, cubeIndices);
glDisableVertexAttribArray(VERTEX_POS_INDEX);
glDisableVertexAttribArray(VERTEX_COLOR_INDEX);
glUseProgram(0);
// flush buffer
glFlush();
[[self openGLContext] flushBuffer];
}
What might the problem be? Oh, and the shaders too:
#version 120
attribute vec3 position;
attribute vec4 inColor;
uniform vec2 offset;
uniform float zNear;
uniform float zFar;
uniform float frustumScale;
varying vec4 outColor;
void main()
{
vec4 cameraPos = vec4(position, 1.0) + vec4(offset.x, offset.y, 0.0, 0.0);
vec4 clipPos;
clipPos.xy = cameraPos.xy * frustumScale;
clipPos.z = cameraPos.z * (zNear + zFar) / (zNear - zFar);
clipPos.z += 2 * zNear * zFar / (zNear - zFar);
clipPos.w = -cameraPos.z;
gl_Position = clipPos;
outColor = inColor;
}
#version 120
varying vec4 outColor;
void main()
{
gl_FragColor = outColor;
}
OK, changed a section of my code to look like this:
GLfloat offset[] = {-2.0, -2.0};
GLint offsetUnif = glGetUniformLocation(programID, "offset");
GLint zNearUnif = glGetUniformLocation(programID, "zNear");
GLint zFarUnif = glGetUniformLocation(programID, "zFar");
GLint frustumScaleUnif = glGetUniformLocation(programID, "frustumScale");
glUniform2fv(offsetUnif, 1, offset);
glUniform1f(frustumScaleUnif, 1.0);
glUniform1f(zNearUnif, 1.0);
glUniform1f(zFarUnif, 25.0);
I get this:
Shouldn't the back end (green) look smaller in the distance and not bigger, like a trapezoid base?
Solution 2
OK, I think I fixed it. Changed my vertex shader to look like this:
#version 120
attribute vec3 position;
attribute vec4 inColor;
uniform vec2 offset;
uniform float zNear;
uniform float zFar;
uniform float frustumScale;
varying vec4 outColor;
void main()
{
vec4 cameraPos = vec4(position.x, position.y, -position.z, 1.0) + vec4(offset.x, offset.y, -10.0, 0.0);
vec4 clipPos;
clipPos.xy = cameraPos.xy * frustumScale;
clipPos.z = cameraPos.z * (zNear + zFar) / (zNear - zFar);
clipPos.z += 2 * zNear * zFar / (zNear - zFar);
clipPos.w = -cameraPos.z;
gl_Position = clipPos;
outColor = inColor;
}
And I get this:
Maybe maybe?
OTHER TIPS
It seems that you're only using buffers and shaders. In this case, you should use OpenGL3.2 and GLSL 1.5. You'll have to manually change to core opengl by changing the context manually in your NSOpenGLView (Or controller).
NSOpenGLPixelFormatAttribute attribute[] =
{
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
0
};
NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribute];
NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
[self setPixelFormat:pixelFormat];
[self setOpenGLContext:context];
But you'll have to change a bit of your shader code, such as your attributes/varyings to in/out.
Then, in regards to your problem, it is required that you create and bind a VAO. Just add
int vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
before you bind your buffers and vertex attrib pointers. And that's it. Nothing more.
Also, I think that your vertices may have some problems to it. Since you're looking at the -Z position, your cube is behind you. So you'll have to change your offset to a vec3, and set the Z offset to -100 seeing how large your cube is.