glDrawElements Patches Crashing

Started by
3 comments, last by Irlan Robson 10 years, 2 months ago

Hi, firstly I would like to say I'm a beginner with OpenGL so sorry if this is a simple fix. I'm trying to draw an Icosahedron following the code here: http://prideout.net/blog/?p=48

When I use


glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);  

everything works OK and I can see the shape on screen. However I need to use GL_PATCHES for tessellation but when I try this:


glDrawElements(GL_PATCHES, indexCount, GL_UNSIGNED_INT, 0); 

it causes the program to crash with "Unhandled exception at 0x697DD6E9 (atioglxx.dll) in TerrainOpenGL.exe: 0xC0000005: Access violation reading location 0x00000054.".

The .h and .cpp files are below. Thanks in advance!


#ifndef ICO_H
#define ICO_H

#include <GL\glew.h>
#include "glm\glm.hpp"
#include "glm\gtc\matrix_transform.hpp"

class Icosahedron {
public:
	Icosahedron();
	~Icosahedron(void);

	void	createIcosahedron();
	void	render(GLuint program);
	void	update(float msec);
	void	updateUniforms(GLuint program);

private:
	GLuint vao;
	GLsizei indexCount;
	glm::mat3	normalMatrix;
	GLuint		LightPosition;
        GLuint		AmbientMaterial;
        GLuint		DiffuseMaterial;
	float		tessLevelInner;
	float		tessLevelOuter;
};

#endif // !--ICO_H


#include "Icosahedron.h"
#include "Mesh.h"
#include <iostream>

Icosahedron::Icosahedron(void) {
	glewInit();
	this->tessLevelInner = 3;
	this->tessLevelOuter = 2;

	glGenVertexArrays(1, &vao);
	createIcosahedron();
}


Icosahedron::~Icosahedron(void) {
	glDeleteVertexArrays(1, &vao);
}

void Icosahedron::createIcosahedron() {
    const int faces[] = {
        2, 1, 0,
        3, 2, 0,
        4, 3, 0,
        5, 4, 0,
        1, 5, 0,

        11, 6,  7,
        11, 7,  8,
        11, 8,  9,
        11, 9,  10,
        11, 10, 6,

        1, 2, 6,
        2, 3, 7,
        3, 4, 8,
        4, 5, 9,
        5, 1, 10,

        2,  7, 6,
        3,  8, 7,
        4,  9, 8,
        5, 10, 9,
        1, 6, 10 
	};

	const float vertices[] = {
         0.000f,  0.000f,  1.000f,
         0.894f,  0.000f,  0.447f,
         0.276f,  0.851f,  0.447f,
        -0.724f,  0.526f,  0.447f,
        -0.724f, -0.526f,  0.447f,
         0.276f, -0.851f,  0.447f,
         0.724f,  0.526f, -0.447f,
        -0.276f,  0.851f, -0.447f,
        -0.894f,  0.000f, -0.447f,
        -0.276f, -0.851f, -0.447f,
         0.724f, -0.526f, -0.447f,
         0.000f,  0.000f, -1.000f 
	};

    indexCount = sizeof(faces) / sizeof(faces[0]);

    // Bind the VAO:
    glBindVertexArray(vao);

    // Create the VBO for positions:
    GLuint positions;
    GLsizei stride = 3 * sizeof(float);
    glGenBuffers(1, &positions);
    glBindBuffer(GL_ARRAY_BUFFER, positions);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(VERTEX_BUFFER);
    glVertexAttribPointer(VERTEX_BUFFER, 3, GL_FLOAT, GL_FALSE, stride, 0);

    // Create the VBO for indices:
    GLuint indices;
    glGenBuffers(1, &indices);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(faces), faces, GL_STATIC_DRAW); 

    glBindVertexArray(0);
}

void Icosahedron::render(GLuint program) {
	updateUniforms(program);

	glBindVertexArray(vao);
	//glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
	glDrawElements(GL_PATCHES, indexCount, GL_UNSIGNED_INT, 0); // CRASH HERE !
	glBindVertexArray(0);
}

void Icosahedron::update(float msec) {
}

void Icosahedron::updateUniforms(GLuint program) {
    glUniform1f(glGetUniformLocation(program, "tessLevelInner"), tessLevelInner);
    glUniform1f(glGetUniformLocation(program, "tessLevelOuter"), tessLevelOuter);
    
    glm::vec4 lightPosition = glm::vec4(0.25f, 0.25f, 1.0f, 0.0f);
    glUniform3fv(glGetUniformLocation(program, "lightPosition"), 1, &lightPosition.x);


    // Render the scene:
    glPatchParameteri(GL_PATCH_VERTICES, 3);
    glUniform3f(glGetUniformLocation(program, "ambientMaterial"), 0.04f, 0.04f, 0.04f);
    glUniform3f(glGetUniformLocation(program, "diffuseMaterial"), 0, 0.75, 0.75);
}
Advertisement

You need to call glUseProgram(). If you do somewhere you didn't include, have you checked glGetError() before the call that crashes?

Are you sure you have attached the tesselation control and evaluation shaders to the program object?

Hi guys, sorry feel a bit embarrassed. Empirical2 I double checked my shaders and it turns out that the evaluation shader had a compilation error that I missed, I fixed that and it now works fine. Thanks for your both your help! :)

A little bit off-topic but If you are starting to OpenGL, you can follow the right path and try to not put OpenGL code inside the shape class itself. Create some wrapper class that encapsulates the OpenGL Objects and some Renderer that owns them (manages its life/creates/destroy/consult).

Other advice: load the model from a file. Hardcode nothing that can be loaded from stream.

Att,

Irlan Robson

This topic is closed to new replies.

Advertisement