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:

Program result

Shouldn't the back end (green) look smaller in the distance and not bigger, like a trapezoid base?

Was it helpful?

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:

program result

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top