PDA

View Full Version : glDrawArrays bad access



Snyder
03-12-2014, 02:20 PM
Casual/hobby programmer here. Probably something super basic going on here (my understanding is basic). When I call glDrawArrays I get a BAD_ACCESS message. For the life of me I can't figure out what it is. Here is the smallest working code that reproduces the error:


#define GLFW_INCLUDE_GLCOREARB //to make glfw3.h include gl3.h instead of gl.h
#include <GLFW/glfw3.h>
#include "ShaderUtils.h"

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

//struct point3 {
// GLfloat x;
// GLfloat y;
// GLfloat z;
//};

int main(){

//Create Window and start glfw
GLint glfwStatus=glfwInit();
if(!glfwStatus){
std::cout<<"window did not load"<<std::endl;
glfwTerminate();
}
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);//3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);//2
GLFWwindow* window=glfwCreateWindow(640, 360, "OpenGL practice", NULL, NULL);
if (window==NULL) {
std::cout<<"did not create window"<<std::endl;
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
std::cout<<glGetString(GL_VERSION)<<std::endl;


//Create Shaders and Program
GLuint vertexShader=shaderUtils::createShaderFromFile("/Users/christophersnyder/Documents/cppprojects/OpenGlTutorial2/vertShader.vs", GL_VERTEX_SHADER);
GLuint fragmentShader=shaderUtils::createShaderFromFile("/Users/christophersnyder/Documents/cppprojects/OpenGlTutorial2/fragsShader.fs", GL_FRAGMENT_SHADER);
GLuint shaderProgram=glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
GLint linkStatus;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &linkStatus);
if (linkStatus!=GL_TRUE) {
std::cout<<"Shader program Failed to link"<<std::endl;
GLint infoLogLength;
glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &infoLogLength);
GLchar* infoLog=new GLchar[infoLogLength+1];
glGetProgramInfoLog(shaderProgram, infoLogLength+1, NULL, infoLog);
delete infoLog;
return 0;
}
glUseProgram(shaderProgram);

//create buffer for axes
const float ticksize=.5;
const int nticks=21;
float tickspacing=.1;

GLfloat ticks[6*nticks];
//xticks
float x_pos;
for (int i=1;i<nticks; i++) {
x_pos= -1 + i * tickspacing;
ticks[i * 6] = x_pos;
ticks[i * 6+1] = -1*ticksize;
ticks[i * 6+2]=0;
ticks[i * 6+3] = x_pos;
ticks[i * 6+4] =ticksize;
ticks[i * 6+5]=0;
}

GLuint axesVBO;
glGenBuffers(1, &axesVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, axesVBO);
glBufferData(axesVBO, sizeof(ticks), ticks, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, NULL);

//create VAO for axes
GLuint axesVAO;
glGenVertexArrays(1, &axesVAO);
glBindVertexArray(axesVAO);
GLint positionLoc=glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(positionLoc);
glBindBuffer(GL_ARRAY_BUFFER, axesVBO);
glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), 0);
glBindBuffer(GL_ARRAY_BUFFER, NULL);
glBindVertexArray(NULL);

//make background black
glClearColor(0.0, 0.0, 0.0, 0.0);

//plotstuff
while( !glfwWindowShouldClose(window)){
GLint windowWidth,windowHeight;
glfwGetWindowSize(window,&windowWidth,&windowHeight);
glViewport(0, 0, windowWidth, windowHeight);
glClear(GL_COLOR_BUFFER_BIT);

glBindVertexArray(axesVAO);
glDrawArrays(GL_LINES, 0, 2*nticks);
//glDrawArrays(GL_LINE_STRIP, 0, 2*nticks);
glBindVertexArray(NULL);


glfwPollEvents();
glfwSwapBuffers(window);
}

glDeleteProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}

//Shaders

#version 410 core

in vec3 position;

void main(){
gl_Position=vec4(position,1.0);
}

#version 410 core


out vec4 fragData;
void main(){
fragData=vec4(1.0,1.0,1.0,1.0);
}

arekkusu
03-12-2014, 06:30 PM
You previously mentioned you're using Xcode. Let me save you a lot of time and point you at an example of setting up the debugger (http://www.opengl.org/discussion_boards/showthread.php/182565-No-polygons-displayed-when-porting-code-from-Windows-to-OS-X?p=1254165&viewfull=1#post1254165).

If your case, if you use the debugger you'll find you're calling glBufferData incorrectly, so your buffer object is never created. Then when you try to draw with it, you are dereferencing unallocated memory and you crash. (You could also determine this by introspecting glGetBufferParameteriv(...GL_BUFFER_SIZE...) just before drawing.)

That's another useful debugging technique, by the way. Learn to introspect state (http://www.idevgames.com/forums/thread-1927-post-53581.html#pid53581).

Snyder
03-17-2014, 09:30 PM
I never got back to you.
Thank you for your help. I got OpenGL profiler up and running. It's not really clear yet how to make use of all of the tonnage it gives me back in the trace, but I'm optimistic. You other link was helpful as well, but probably not helpful enough that you won't be hearing from me ever again ;)