0 Replies - 556 Views - Last Post: 20 October 2019 - 11:13 PM Rate Topic: -----

#1 prabh   User is offline

  • D.I.C Regular
  • member icon

Reputation: 3
  • View blog
  • Posts: 383
  • Joined: 27-December 08

Polygon tearing in OpenGL

Posted 20 October 2019 - 11:13 PM

#include <iostream>
#include <sstream>
#include <vector>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"

#include "GameEngine.hpp"
#include "ShaderProgram.h"
#include "Camera.h"
#include "Mesh.h"

const char *title = "Terrain";

GameEngine engine;
OrbitCamera orbitCamera;
float gYaw = 0.0f;
float gPitch = 1.0f;
float gRadius = 200.0f;
const float MOUSE_SENSTIVITY = 0.25f;

bool gWireFrame = false;
void glfw_onKey(GLFWwindow *window, int key, int scancode, int action, int mode);
void glfw_onmousemove(GLFWwindow *window, double posX, double posY);
void glfw_onMouseScroll(GLFWwindow *window, double deltaX, double deltaY);

int main()
{
    if (!engine.init(1024, 768, title))
    {
        std::cerr << "OpenGL init failed" << std::endl;
        std::cin.get();
        return -1;
    }

    //set callbacks
    glfwSetKeyCallback(engine.getWindow(), glfw_onKey);
    glfwSetCursorPosCallback(engine.getWindow(), glfw_onmousemove);

    std::vector<Vertex> VER;

    std::vector<glm::vec3> verts;
    std::vector<unsigned int> indices;
    std::vector<glm::vec3> norms;

    int subDiv = 1000;
    int width = 500;
    int height = 500;
    int size = 0;

    for (int row = 0; row < subDiv; row++)
    {
        for (int col = 0; col < subDiv; col++)
        {
            float x = (float)((col * width) / subDiv - (width / 2.0));
            float z = ((subDiv - row) * height) / subDiv - (height / 2.0);
            glm::vec3 pos = glm::vec3(x, 0, z);
            verts.push_back(pos);
        }
    }

    size = subDiv * subDiv;

    size = verts.size();

    for (int row = 0; row < subDiv -1 ; row++)
    {
        for (int col = 0; col < subDiv -1; col++)
        {
             int row1 = row * (subDiv);
            int row2 = (row+1) * (subDiv);

            indices.push_back(row1+col);
            indices.push_back(row1+col+1);
            indices.push_back( row2+col+1);

            indices.push_back(row1+col);
            indices.push_back( row2+col+1);
            indices.push_back(row2+col);
        }
    }


    for (int i = 0; i < verts.size(); i++)
    {
        Vertex vertex;
        vertex.position = verts[i];

        vertex.normal = glm::vec3(0, 0, 0);
        vertex.texCoords = glm::vec2(0, 0);

        VER.push_back(vertex);
    }

    VER.begin();

    for (int i = 0; i < indices.size(); i += 3)
    {
        Vertex a = VER[indices[i]];
        Vertex b = VER[indices[i + 1]];
        Vertex c = VER[indices[i + 2]];

        glm::vec3 p = glm::cross(b.position - a.position, c.position - a.position);

        VER[indices[i]].normal += p;
        VER[indices[i + 1]].normal += p;
        VER[indices[i + 2]].normal += p;
    }

    for (int i = 0; i < VER.size(); i++)
    {
        VER[i].normal = glm::normalize(VER[i].normal);
    }

    

    glm::vec3 cubePos = glm::vec3(0.0f, 0.0f, -5.0f);

    GLuint vbo, vao, ibo;

    glGenVertexArrays(1, &vao);
    glGenBuffers(1, &vbo);
    
    glBindVertexArray(vao);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, VER.size() * sizeof(Vertex), &VER[0], GL_STATIC_DRAW);
    

// Vertex Positions
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);
	glEnableVertexAttribArray(0);

	// Normals attribute
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(3 * sizeof(GLfloat)));
	glEnableVertexAttribArray(1);

	// Vertex Texture Coords
	glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(6 * sizeof(GLfloat)));
	glEnableVertexAttribArray(2);

    int n = indices.size() * sizeof(unsigned int);


    glGenBuffers(1, &ibo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);


    glBindVertexArray(0);

    ShaderProgram shaderProgram;
    shaderProgram.loadShaders("shaders/vert.glsl", "shaders/frag.glsl");
    //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    while (!glfwWindowShouldClose(engine.getWindow()))
    {

        glfwPollEvents();

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glm::mat4 model, view, projection;

        model = glm::mat4(1.0f);

        orbitCamera.setLookAt(glm::vec3(0, 0, 0));
        orbitCamera.rotate(gYaw, gPitch);
        orbitCamera.setRadius(gRadius);

        model = glm::translate(model, glm::vec3(0, 0, 0));
        //model = glm::scale(model, glm::vec3(1, 0, 1));

        //model = scaleMat;

        projection = glm::perspective(glm::radians(45.0f), (float)engine.getWidth() / (float)engine.getHeight(), 0.00001f, 100.0f);

        shaderProgram.use();
        glm::vec3 viewPos;
        viewPos.x = orbitCamera.getPosition().x;
        viewPos.y = orbitCamera.getPosition().y;
        viewPos.z = orbitCamera.getPosition().z;

        shaderProgram.setUniform("projection", projection);
        shaderProgram.setUniform("view", orbitCamera.getViewMatrix());
        shaderProgram.setUniform("model", model);
        shaderProgram.setUniform("lightPos", glm::vec3(5, 10, 10));
        shaderProgram.setUniform("viewPos", viewPos);

        glBindVertexArray(vao);
        glDrawElements(GL_TRIANGLES,indices.size(), GL_UNSIGNED_INT, 0);
        //glDrawArrays(GL_TRIANGLES, 0, VER.size());
        glBindVertexArray(0);

        glfwSwapBuffers(engine.getWindow());
    }

    //cleanup
    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(1, &vbo);

    glfwTerminate();
    return 0;
}

void glfw_onKey(GLFWwindow *window, int key, int scancode, int action, int mode)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
    {
        glfwSetWindowShouldClose(window, GL_TRUE);
    }

    if (key == GLFW_KEY_E && action == GLFW_PRESS)
    {
        gWireFrame = !gWireFrame;
        if (gWireFrame)
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        else
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    }
}

void glfw_onmousemove(GLFWwindow *window, double posX, double posY)
{
    static glm::vec2 lastMousePos = glm::vec2(0, 0);
    if (glfwGetMouseButton(engine.getWindow(), GLFW_MOUSE_BUTTON_LEFT) == 1)
    {
        gYaw -= ((float)posX - lastMousePos.x) * MOUSE_SENSTIVITY;
        gPitch += ((float)posY - lastMousePos.y) * MOUSE_SENSTIVITY;
    }
    if (glfwGetMouseButton(engine.getWindow(), GLFW_MOUSE_BUTTON_RIGHT) == 1)
    {
        float dx = 0.01f * ((float)posX - lastMousePos.x);
        float dy = 0.01f * ((float)posY - lastMousePos.y);
        gRadius += dx - dy;
    }
    lastMousePos.x = (float)posX;
    lastMousePos.y = (float)posY;
}



Above code resulted in this:
Posted Image

After changing the farplane value to 8000 I got this:
Posted Image

How to make it perfect ?

PS: I can code for other classes if required.

Is This A Good Question/Topic? 0
  • +

Page 1 of 1