Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: render a quad - blank screen

  1. #1
    Junior Member Newbie
    Join Date
    Feb 2013
    Posts
    26

    render a quad - blank screen

    Hi

    I believe that this something every opengl programmer encounter initially . I am trying to render a quad as follows:

    Code :
    void loadGeometry()
    {
       //load the vertices for the floor
     
       //make and bind the vertex array object
       glGenVertexArrays(1,&gVAO);
       glBindVertexArray(gVAO);
     
       //make and bind the vertex buffer object
       glGenBuffers(1,&gVBO);
       glBindBuffer(GL_ARRAY_BUFFER,gVBO);
     
       //put the quad verteices and texture coordinates into the VBO
     
       GLfloat vertexData[] = {-20.0f,0.0f,-20.0f, 0.0f,0.0f,
    			   20.0f,0.0f,-20.0f,  20.0f,0.0f,
    			   20.0f,0.0f,20.0f,  20.0f,20.0f,
    			   -20.0f,0.0f,20.0f,  0.0f,20.0f};
     
     
       glBufferData(GL_ARRAY_BUFFER,sizeof(vertexData),vertexData,GL_STATIC_DRAW);
     
       //connect the xyz of the vertexData to the "position" attribute of the vertex shader
       glEnableVertexAttribArray(floorProgram->attrib("position"));
       glVertexAttribPointer(floorProgram->attrib("position"),3,GL_FLOAT,GL_FALSE,5*sizeof(GLfloat),NULL);
     
       //connect the uv coordinates to the "posTexCoord" attribute of the vertex shader
       glEnableVertexAttribArray(floorProgram->attrib("posTexCoord"));
       glVertexAttribPointer(floorProgram->attrib("posTexCoord"),2,GL_FLOAT,GL_TRUE,
    			 5*sizeof(GLfloat),
    			 (const GLvoid*)(3 * sizeof(GLfloat)));
     
       //unbind the vertex array object
       glBindVertexArray(0);
       floorProgram->stopUsing();
    }

    And then i am rendering with the following snippet:

    Code :
    void render(double time)
    {
       static const GLfloat one = 1.0f;
     
       glViewport(0,0,winWidth,winHeight);
     
       glClearBufferfv(GL_COLOR,0,backgroundcolor);
       glClearBufferfv(GL_DEPTH,0,&one);
     
       //use the floor program
       floorProgram->use();
     
       //the floor texture is already bound, no need to bind it again
     
       glActiveTexture(GL_TEXTURE0);
       glBindTexture(GL_TEXTURE_2D,floorTex);
     
       floorProgram->setUniform("tex",floorTex);
     
       //send the camera matrix to the shader
       floorProgram->setUniform("camera",camera->matrix());
     
     
       //bind the VAO - the quad
       glBindVertexArray(gVAO);
     
       //draw the VAO - the quad
       glDrawArrays(GL_TRIANGLES,0,1*2*3);
     
       //unbind the VAO
       glBindVertexArray(0);
       glBindTexture(GL_TEXTURE_2D,0);
     
       floorProgram->stopUsing();
    }

    I am getting blank screen, and now i am clueless. I am not sure about the parameter of the glDrawArrays(..) though. A quad could be rendered as - one face with 2 triangles and each triangle with 3 vertices. So in total we shall be dealing with 3*2 = 6 elements to be rendered. Is it right ?

    The camera is initialized as follows:

    Code :
       camera = new tdogl::Camera();
       camera->setPosition(glm::vec3(1,0,9));
       camera->setViewportAspectRatio((float)winWidth/winHeight);

    I have changed the camera position as well, but no sight of the quad.

    Some hint is appreciated to find the quad!


    Thanks

  2. #2
    Intern Contributor
    Join Date
    Mar 2014
    Location
    San Jose, CA
    Posts
    58
    Does your vertex shader apply any transformation? I notice that your vertices all have 0.0 for the y coordinate. While I'm not familiar with the camera class you're using, I suspect that it points in the negative z direction by default. So your quad would be degenerate if all y coordinates are identical, which means that no pixels are drawn. If this is your main problem, you either have to change your vertex coordinates to extend in the x and y direction, and use the same value for all z coordinates. Or change the direction the camera points.

    I see a few other issues in your code:
    • Your texture coordinates are in the range 0.0 to 20.0. Unless you intentionally plan to repeat your texture 20 times in each direction, you'll probably want to use 0.0 to 1.0 as the range of your texture coordinates.
    • The value of a uniform variable for a texture sampler is the texture unit, not the texture id. Since you bind the texture to unit 0, you will want to pass 0 instead of floorTex to that setUniform() call.
    • If you want to draw the quad with the 4 vertices you defined, you need to pass 4 as the 3rd argument to glDrawArrays(), and use GL_QUADS (deprecated) or GL_TRIANGLE_MESH (with 3rd and 4th vertex swapped). If you want to use GL_TRIANGLES, you will need 6 vertices in your vertex array.
    Last edited by reto.koradi; 03-30-2014 at 09:15 PM. Reason: formatting

  3. #3
    Junior Member Newbie
    Join Date
    Feb 2013
    Posts
    26
    Yes, the vertex shader is applying the transformation as follows:

    Code :
    #version 430 core
     
    uniform mat4 camera;
    //uniform mat4 modelview;
     
    in vec3 position;
    in vec2 posTexCoord;
    out vec2 fragTexCoord;
     
    void main()
    {
            // apply all the matrix multiplication to the vertex shader
    	gl_Position = camera  * modelview *  vec4(position,1);
     
    	//pass the tex coordinate straight through to the fragment shader
    	fragTexCoord = posTexCoord;
    }

    And here goes all the details of the camera class:

    Code :
    #define _USE_MATH_DEFINES
    #include <cmath>
    #include "Camera.h"
    #include <glm/gtc/matrix_transform.hpp>
     
    using namespace tdogl;
     
    static const float MaxVerticalAngle = 85.0f; //must be less than 90 to avoid gimbal lock
     
    static inline float RadiansToDegrees(float radians)
    {
        return radians * 180.0f / (float)M_PI;
    }
     
     
    Camera::Camera() :
        _position(0.0f, 0.0f, 1.0f),
        _horizontalAngle(0.0f),
        _verticalAngle(0.0f),
        _fieldOfView(50.0f),
        _nearPlane(0.01f),
        _farPlane(100.0f),
        _viewportAspectRatio(4.0f/3.0f)
    {
    }
     
    const glm::vec3& Camera::position() const {
        return _position;
    }
     
    void Camera::setPosition(const glm::vec3& position) {
        _position = position;
    }
     
    void Camera::offsetPosition(const glm::vec3& offset) {
        _position += offset;
    }
     
    float Camera::fieldOfView() const {
        return _fieldOfView;
    }
     
    void Camera::setFieldOfView(float fieldOfView) {
        assert(fieldOfView > 0.0f && fieldOfView < 180.0f);
        _fieldOfView = fieldOfView;
    }
     
    float Camera::nearPlane() const {
        return _nearPlane;
    }
     
    float Camera::farPlane() const {
        return _farPlane;
    }
     
    void Camera::setNearAndFarPlanes(float nearPlane, float farPlane) {
        assert(nearPlane > 0.0f);
        assert(farPlane > nearPlane);
        _nearPlane = nearPlane;
        _farPlane = farPlane;
    }
     
    glm::mat4 Camera::orientation() const {
        glm::mat4 orientation;
        orientation = glm::rotate(orientation, _verticalAngle, glm::vec3(1,0,0));
        orientation = glm::rotate(orientation, _horizontalAngle, glm::vec3(0,1,0));
        return orientation;
    }
     
    void Camera::offsetOrientation(float upAngle, float rightAngle) {
        _horizontalAngle += rightAngle;
        _verticalAngle += upAngle;
        normalizeAngles();
    }
     
    void Camera::lookAt(glm::vec3 position) {
        assert(position != _position);
        glm::vec3 direction = glm::normalize(position - _position);
        _verticalAngle = RadiansToDegrees(asinf(-direction.y));
        _horizontalAngle = -RadiansToDegrees(atan2f(-direction.x, -direction.z));
        normalizeAngles();
    }
     
    float Camera::viewportAspectRatio() const {
        return _viewportAspectRatio;
    }
     
    void Camera::setViewportAspectRatio(float viewportAspectRatio) {
        assert(viewportAspectRatio > 0.0);
        _viewportAspectRatio = viewportAspectRatio;
    }
     
    glm::vec3 Camera::forward() const {
        glm::vec4 forward = glm::inverse(orientation()) * glm::vec4(0,0,-1,1);
        return glm::vec3(forward);
    }
     
    glm::vec3 Camera::right() const {
        glm::vec4 right = glm::inverse(orientation()) * glm::vec4(1,0,0,1);
        return glm::vec3(right);
    }
     
    glm::vec3 Camera::up() const {
        glm::vec4 up = glm::inverse(orientation()) * glm::vec4(0,1,0,1);
        return glm::vec3(up);
    }
     
    glm::mat4 Camera::matrix() const {
        return projection() * view();
    }
     
    glm::mat4 Camera::projection() const {
        return glm::perspective(_fieldOfView, _viewportAspectRatio, _nearPlane, _farPlane);
    }
     
    glm::mat4 Camera::view() const {
        return orientation() * glm::translate(glm::mat4(), -_position);
    }
     
    void Camera::normalizeAngles() {
        _horizontalAngle = fmodf(_horizontalAngle, 360.0f);
        //fmodf can return negative values, but this will make them all positive
        if(_horizontalAngle < 0.0f)
            _horizontalAngle += 360.0f;
     
        if(_verticalAngle > MaxVerticalAngle)
            _verticalAngle = MaxVerticalAngle;
        else if(_verticalAngle < -MaxVerticalAngle)
            _verticalAngle = -MaxVerticalAngle;
    }

    I am trying the port an old opengl application to the modern opengl. And the existing opengl application create the quad plane as follows:

    Code :
       // view transform
       glMatrixMode(GL_MODELVIEW);
       glLoadIdentity();
     
       glRotatef(cameraRotLag[0], 1.0, 0.0, 0.0);
       glRotatef(cameraRotLag[1], 0.0, 1.0, 0.0);
       glTranslatef(cameraPosLag[0], cameraPosLag[1], cameraPosLag[2]);
     
       //pull out the model-view matrix
       glGetFloatv(GL_MODELVIEW_MATRIX, modelView);
    ...........................................
    ...........................................
     
        glBegin(GL_QUADS);
        {
            float s = 20.f;
            float rep = 20.f;
            glTexCoord2f(0.f, 0.f);glVertex3f(-s, 0, -s);
            glTexCoord2f(rep, 0.f);glVertex3f(s, 0, -s);
            glTexCoord2f(rep, rep);glVertex3f(s, 0, s);
            glTexCoord2f(0.f, rep);glVertex3f(-s, 0, s);
        }
        glEnd();

    What do i have to rethink here ?

    And to answer some of the issues that you have raised:

    1. Yes, i do want to repeat the texture as you may have noticed in the existing opengl code.
    2. Thanks for pointing it out!. I did the necessary changes, but it did not change the output
    3. I am using GL_TRIANGLES .

    Since you have the snippet of the old opengl now. Some suggestions is appreciated to fit it within the new paradigm

    Thanks

  4. #4
    Junior Member Newbie
    Join Date
    Feb 2013
    Posts
    26
    Quote Originally Posted by reto.koradi View Post
    Does your vertex shader apply any transformation?
    Yes i m doing the transformation in the vertex shader
    Quote Originally Posted by reto.koradi View Post
    I notice that your vertices all have 0.0 for the y coordinate. While I'm not familiar with the camera class you're using, I suspect that it points in the negative z direction by default. So your quad would be degenerate if all y coordinates are identical, which means that no pixels are drawn. If this is your main problem, you either have to change your vertex coordinates to extend in the x and y direction, and use the same value for all z coordinates. Or change the direction the camera points.
    In that case , should i not see a floor bottom and the camera is looking down to the negative z-direction ? The camera up vector is (0,1,0). I am creating a perspective camera which you have noticed in my previous post. I did not get why do i need to change the direction that the camera points to.

    Thanks

  5. #5
    Intern Contributor
    Join Date
    Mar 2014
    Location
    San Jose, CA
    Posts
    58
    Hmm, ok. I still suspect that your camera is not pointing at the quad. In the old code, there's a couple of glRotate*() and a glTranslate*() calls that go into the MODELVIEW matrix. In the vertex shader you copied, you do apply a modelview matrix as well. But does your new code set a value for it? In fact, in the vertex shader you copied, the variable declaration for modelview is commented out. So I don't think the shader would compile in this form. You may want to verify that the shaders compile successfully.

    Beyond that, it looks like your camera points in the negative z direction, and your quad coordinates are in the xz plane. If that's the case, you will either need to make sure that a rotation is applied to the quad, or put the coordinates in the xy plane instead.

    To get the proper perspective, you'll also need to set up a projection matrix, and apply it in your vertex shader. Should not be critical to at least see anything showing up, though.

    You'll also need to match up your vertex definitions and your draw call. With your original draw call, you're trying to use 6 vertices, but only 4 are defined. Either add 2 more vertices so that you have the 6 vertices needed for two independent triangles. Or as I suggested in my previous post, use a different primitive type that only needs 4 vertices for the quad, and change the primitive type and number of vertices in the draw call accordingly.

    The camera is pretty close as well, being only 9 units away from a 40x40 size quad. You should still see something so if everything else is correct, even if it's only a small part of the quad.

    The texture setup could be another potential problem. To debug these types of issues, I often just set a constant color in the fragment shader. This allows you to see if the geometry is placed properly, excluding other issues like texture setup.

  6. #6
    Junior Member Newbie
    Join Date
    Feb 2013
    Posts
    26
    Quote Originally Posted by reto.koradi View Post
    Hmm, ok. I still suspect that your camera is not pointing at the quad. In the old code, there's a couple of glRotate*() and a glTranslate*() calls that go into the MODELVIEW matrix. In the vertex shader you copied, you do apply a modelview matrix as well. But does your new code set a value for it? In fact, in the vertex shader you copied, the variable declaration for modelview is commented out. So I don't think the shader would compile in this form. You may want to verify that the shaders compile successfully.
    Sorry for posting the buggy code. I am actually not doing any model-view transformation at all.

    Quote Originally Posted by reto.koradi View Post
    Beyond that, it looks like your camera points in the negative z direction, and your quad coordinates are in the xz plane. If that's the case, you will either need to make sure that a rotation is applied to the quad, or put the coordinates in the xy plane instead.
    I fixed the issue as follows:

    Code :
       static const GLfloat vertexData[] =
          {
    	 -20.0f,-1.0f,-20.0f,   0.0f,0.0f,   // 0
    	 20.0f, -1.0f,-20.0f,   20.0f,0.0f,  // 1
    	 20.0f, -1.0f,20.0f,    20.0f,20.0f, // 2
    	 -20.0f,-1.0f,20.0f,    0.0f,20.0f   // 3
          };   
     
       static const GLushort vertex_indices[] =
          {
    	 0,1,3,
    	 1,2,3	 
          };

    Quote Originally Posted by reto.koradi View Post
    To get the proper perspective, you'll also need to set up a projection matrix, and apply it in your vertex shader. Should not be critical to at least see anything showing up, though.
    I am setting the perspective as follows by the camera class that i attached in my previous post over the same issue:

    Code :
       gCamera.setPosition(glm::vec3(1,0,9));
       gCamera.setViewportAspectRatio((float)winWidth/winHeight);

    The camera is perspective one by default

    Quote Originally Posted by reto.koradi View Post
    You'll also need to match up your vertex definitions and your draw call. With your original draw call, you're trying to use 6 vertices, but only 4 are defined. Either add 2 more vertices so that you have the 6 vertices needed for two independent triangles. Or as I suggested in my previous post, use a different primitive type that only needs 4 vertices for the quad, and change the primitive type and number of vertices in the draw call accordingly.
    Thanks for the correction!

    Check the url
    http://imgur.com/t7cQl2c

    I got something new now!
    As you can see the the window is expanded , but the viewport is not adjusted. I have the callback defined as follows:

    Code :
       glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    ....................
    ....................
     
    void framebuffer_size_callback(GLFWwindow* window, int width, int height)
    {
       float ratio = 1.0f;
     
       if(height > 0)
          ratio = (float)width / (float)height;
     
       //setup the viewport
       glViewport(0,0,width,height);
     
    }

    What is it i am missing now?

    Thanks for your effort over this issue!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •