为啥glDrawArrays不总是出现预期的图像呢?

各位大神你们好。
平台是iOS,用的工具是OpenGLES2.0,开发语言是Objective-C。
问题如下。
我现在试图使用OpenGLES2.0的顶点模式绘制线条,现在我以每条线条为单位,这里面每条线条都是若干个点的数据的集合。
每个线条我用一个数据模型来存储,数据模型中有一个NSData的属性来存储该数据模型对应的线条的所有的点的字节数据。
因为线条不是一条,所以我用C语法创建了一个GLuint类型的动态数组。
当我在要绘制这些线条的时候,我使用VAO数组中的一个来生成VAO,绑定VAO,然后创建VBO,VBO中使用的数据是数据模型中的NSData中的字节,绑定好VAO以后,我就把VBO删除了。
在这里我要强调的是数据模型和VAO数组中的元素都是一一对应的,不会出现错乱。
在渲染阶段,我也是顺次对各个VAO进行渲染,使用的是glDrawArrays方法,这里面用的是for循环。
而且在每次glDrawArrays之后我都会调用glFlush();glFinish();的。
这里面一次渲染是进行了若干次绘制,这若干次绘制就是用for循环来做的。
但是出来的效果并不是每次绘制都会出现预想的效果,就是说有些渲染并没有新的图像出现,请问这是为什么?

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
OpenGL不能同时使用glDrawElements和glDrawArrays绘制两个不同的模型吗?
学习OpenGL的时候碰到一个奇怪的问题。刚学到了OpenGL可以使用glDrawElements或者glDrawArrays两种方式来绘制图元。我就想练习一下这两种不同的绘图方式。然后**在同一个渲染循环中**分别使用 **glDrawElements绘制第一个模型**,**glDrawArrays绘制第二个模型**,奇怪的问题出现了,只有glDrawArrays这个绘图有效,但是我把绘制第二个模型的代码段注释起来后,第一个也是可以正常绘制的,也就是说**在同一个渲染循环中不能同时使用glDrawElements和glDrawArrays这两个函数**?我猜测OpenGL应该不会犯这么傻的错误,但是我实在不知道我代码哪里出了问题,请大佬们帮忙看看到底是哪里出了问题。 下面贴上我的代码片段: --- ```c++ //准备第一个模型vbo,vao,ebo GLuint vbo, ebo, vao; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index), index, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glGenVertexArrays(1, &vao); ``` --- ```c++ //准备第二个模型vbo,vao GLuint sanvbo, sanvao; glGenBuffers(1, &sanvbo); glBindBuffer(GL_ARRAY_BUFFER, sanvbo); glBufferData(GL_ARRAY_BUFFER, sizeof(san), san, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenVertexArrays(1, &sanvao); ``` --- ```c++ //渲染过程 //第一个模型:使用glDrawElements渲染 glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBindVertexArray(vao); glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(0); glDrawElements(GL_LINES, sizeof(index) / sizeof(GLuint), GL_UNSIGNED_INT, 0); ``` --- ```c++ //第二个模型,使用glDrawArrays渲染 glBindBuffer(GL_ARRAY_BUFFER, sanvbo); glBindVertexArray(sanvao); glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * sizeof(GLfloat), nullptr); glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLES, 0, sizeof(san) / sizeof(float)); ``` --- 如上面代码段所示,如果我只单独的绘制一个模型,两个都可以正常绘制。但是一次绘制两个的时候就只有第二个被绘制出来了,第一个始终没有,不知道到底是哪里出了问题。
安卓 GLES20.glDrawArrays 在小米手机上报错
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, firstVertex, vertexCount)在小米手机报错 #3707 SIGSEGV(SEGV_MAPERR)
OpenGL图像显示和别人不一样
用老师给的源代码,原封不动运行,图像异常 原本应该是这样的 ![原本的样子](https://img-ask.csdn.net/upload/201909/20/1568908959_14748.png) 然后我电脑上是这样子的 ![我运行出来的样子](https://img-ask.csdn.net/upload/201909/20/1568908978_338083.png) 下面附上main.cpp的代码 (第一次遇到这样的问题,百度谷歌弄了一下午,把VS2013卸载安装了2019,还是搞不定,求大神帮忙,感激不尽) ``` #include "Angel.h" #pragma comment(lib, "glew32.lib") const int MENU_CHOICE_WHITE = 0; const int MENU_CHOICE_BLACK = 1; const int MENU_CHOICE_RED = 2; const int MENU_CHOICE_GREEN = 3; const int MENU_CHOICE_BLUE = 4; const int MENU_CHOICE_YELLOW = 5; const int MENU_CHOICE_ORANGE = 6; const int MENU_CHOICE_PURPLE = 7; const vec3 WHITE(1.0, 1.0, 1.0); const vec3 BLACK(0.0, 0.0, 0.0); const vec3 RED(1.0, 0.0, 0.0); const vec3 GREEN(0.0, 1.0, 0.0); const vec3 BLUE(0.0, 0.0, 1.0); const vec3 YELLOW(1.0, 1.0, 0.0); const vec3 ORANGE(1.0, 0.65, 0.0); const vec3 PURPLE(0.8, 0.0, 0.8); // 主窗口变量 const int SQUARE_NUM = 6; const int SQUARE_NUM_POINTS = 4 * SQUARE_NUM; int mainWindow; int mainWindowMenu; int mainWindowSubmenu; int width = 600; // 主窗口宽度 int height = 600; // 主窗口高度 double offsetAngle = 0; // 角度偏移量 double delta = 0.05; // 每次改变角度偏移的变化量 vec3 mainWindowSquareColor = WHITE; // 子窗口变量 const int ELLIPSE_NUM_POINTS = 100; int subWindow; int subWindowMenu; vec3 subWindowObjectColor = RED; // 获得圆上的点 vec2 getEllipseVertex(vec2 center, double scale, double verticleScale, double angle) { vec2 vertex(sin(angle), cos(angle)); vertex += center; vertex *= scale; vertex.y *= verticleScale; // 修改垂直分量 return vertex; } // 生成圆上顶点的属性 void generateEllipsePoints(vec2 vertices[], vec3 colors[], vec3 color, int startVertexIndex, int numPoints, vec2 center, double scale, double verticalScale) { double angleIncrement = (2 * M_PI) / numPoints; double currentAngle = M_PI / 2; for (int i = startVertexIndex; i < startVertexIndex + numPoints; i++) { vertices[i] = getEllipseVertex(center, scale, verticalScale, currentAngle); colors[i] = color; currentAngle += angleIncrement; } } // 获得正方形的每个角度 double getSquareAngle(int point) { return (M_PI / 4 + (M_PI / 2 * point)) + offsetAngle; } // 生成正方形上顶点的属性 void generateSquarePoints(vec2 vertices[], vec3 colors[], int squareNum, int startVertexIndex) { double scale = 0.90; double scaleAdjust = scale / squareNum; vec2 center(0.0, -0.25); int vertexIndex = startVertexIndex; for (int i = 0; i < squareNum; i++) { vec3 currentColor = 0 == i % 2 ? mainWindowSquareColor : BLACK; for (int j = 0; j < 4; j++) { double currentAngle = getSquareAngle(j); vertices[vertexIndex] = vec2(sin(currentAngle), cos(currentAngle)) * scale + center; colors[vertexIndex] = currentColor; vertexIndex++; } scale -= scaleAdjust; } } // 空闲回调函数 void idleFunction() { // 改变角度的偏移量 offsetAngle += delta; // 标记主窗口重绘 glutPostWindowRedisplay(mainWindow); } void mainWindowInit() { vec2 vertices[SQUARE_NUM * 4]; vec3 colors[SQUARE_NUM * 4]; // 创建主窗口中多个正方形 generateSquarePoints(vertices, colors, SQUARE_NUM, 0); // 创建顶点数组对象 GLuint vao[1]; glGenVertexArrays(1, vao); glBindVertexArray(vao[0]); // 创建并初始化顶点缓存对象 GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(colors), NULL, GL_STATIC_DRAW); // 分别读取数据 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(colors), colors); // 读取着色器并使用 GLuint program = InitShader("vshader.glsl", "fshader.glsl"); glUseProgram(program); // 从顶点着色器中初始化顶点的位置 GLuint pLocation = glGetAttribLocation(program, "vPosition"); glEnableVertexAttribArray(pLocation); glVertexAttribPointer(pLocation, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); // 从片元着色器中初始化顶点的颜色 GLuint cLocation = glGetAttribLocation(program, "vColor"); glEnableVertexAttribArray(cLocation); glVertexAttribPointer(cLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(vertices))); // 黑色背景 glClearColor(0.0, 0.0, 0.0, 1.0); } // 菜单回调函数 void mainWindowMenuEvents(int menuChoice) { switch (menuChoice) { case MENU_CHOICE_WHITE: mainWindowSquareColor = WHITE; break; case MENU_CHOICE_BLACK: mainWindowSquareColor = BLACK; break; case MENU_CHOICE_RED: mainWindowSquareColor = RED; break; case MENU_CHOICE_GREEN: mainWindowSquareColor = GREEN; break; case MENU_CHOICE_BLUE: mainWindowSquareColor = BLUE; break; case MENU_CHOICE_YELLOW: mainWindowSquareColor = YELLOW; break; case MENU_CHOICE_ORANGE: mainWindowSquareColor = ORANGE; break; case MENU_CHOICE_PURPLE: mainWindowSquareColor = PURPLE; break; /*在此处添加控制旋转动画开始和停止的菜单选项*/ } // 标记mainWindow主窗口进行重绘 glutPostWindowRedisplay(mainWindow); } // 创建和设置主窗口菜单 void mainWindowSetupMenu() { // 创建子菜单,并注册菜单回调函数mainWindowMenuEvents mainWindowSubmenu = glutCreateMenu(mainWindowMenuEvents); glutAddMenuEntry("Yellow", MENU_CHOICE_YELLOW); glutAddMenuEntry("Orange", MENU_CHOICE_ORANGE); glutAddMenuEntry("Purple", MENU_CHOICE_PURPLE); glutAddMenuEntry("Black", MENU_CHOICE_BLACK); // 创建主菜单 mainWindowMenu = glutCreateMenu(mainWindowMenuEvents); glutAddMenuEntry("Red", MENU_CHOICE_RED); glutAddMenuEntry("Green", MENU_CHOICE_GREEN); glutAddMenuEntry("Blue", MENU_CHOICE_BLUE); glutAddMenuEntry("White", MENU_CHOICE_WHITE); // 在主菜单中添加子菜单 glutAddSubMenu("Other Square Colors", mainWindowSubmenu); // 关联鼠标右键激活菜单 glutAttachMenu(GLUT_RIGHT_BUTTON); } void mainWindowDisplay() { mainWindowInit(); // 重绘时写入新的颜色数据 glClear(GL_COLOR_BUFFER_BIT); for (int i = 0; i < SQUARE_NUM; i++) { glDrawArrays(GL_TRIANGLE_FAN, (i * 4), 4); } glutSwapBuffers(); } // 主窗口键盘回调函数 void mainWindowKeyboard(unsigned char key, int x, int y) { /*在此添加按下Esc按键退出的代码*/ } // 主窗口鼠标回调函数 void mainWindowMouse(int button, int state, int x, int y) { if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) { // 按下鼠标中键,指定当没有其他事件处理时,去调用idleFunction()这个函数 glutIdleFunc(idleFunction); } else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_UP) { // 释放鼠标中键,解除调用 glutIdleFunc(NULL); } } void subWindowInit() { vec2 vertices[ELLIPSE_NUM_POINTS]; vec3 colors[ELLIPSE_NUM_POINTS]; // 创建子窗口中的椭圆 generateEllipsePoints(vertices, colors, subWindowObjectColor, 0, ELLIPSE_NUM_POINTS, vec2(0.0, 0.0), 0.7, 0.5); // 创建顶点数组对象 GLuint vao[1]; glGenVertexArrays(1, vao); glBindVertexArray(vao[0]); // 创建并初始化顶点缓存对象 GLuint buffer; glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(colors), NULL, GL_STATIC_DRAW); // 分别读取数据 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(colors), colors); // 读取着色器并复用 GLuint program = InitShader("vshader.glsl", "fshader.glsl"); glUseProgram(program); // 从顶点着色器中初始化顶点的位置 GLuint pLocation = glGetAttribLocation(program, "vPosition"); glEnableVertexAttribArray(pLocation); glVertexAttribPointer(pLocation, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); // 从片元着色器中初始化顶点的颜色 GLuint cLocation = glGetAttribLocation(program, "vColor"); glEnableVertexAttribArray(cLocation); glVertexAttribPointer(cLocation, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(vertices))); // 设置子窗口背景颜色为白色 glClearColor(1.0, 1.0, 1.0, 1.0); } void subWindowDisplay() { subWindowInit(); // 重绘时写入新的颜色数据 glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLE_FAN, 0, ELLIPSE_NUM_POINTS); glutSwapBuffers(); } // 子窗口键盘回调函数 void subWindowKeyboard(unsigned char key, int x, int y) { switch (key) { case 'r': subWindowObjectColor = RED; break; case 'g': subWindowObjectColor = GREEN; break; case 'b': subWindowObjectColor = BLUE; break; case 'y': subWindowObjectColor = YELLOW; break; case 'o': subWindowObjectColor = ORANGE; break; case 'p': subWindowObjectColor = PURPLE; break; case 'w': subWindowObjectColor = WHITE; break; } // 标记subWindow子窗口进行重绘 glutPostWindowRedisplay(subWindow); } void printHelp() { printf("%s\n\n", "Interaction and Submenu"); printf("Keys to update the background color in sub window:\n"); printf("'r' - red\n'g' - green\n'b' - blue\n'y' - yellow\n'o' - orange\n'p' - purple\n'w' - white\n"); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); // 启用双重缓冲 glutInitWindowSize(width, height); mainWindow = glutCreateWindow("Interaction and Submenu"); glewExperimental = GL_TRUE; glewInit(); mainWindowInit(); mainWindowSetupMenu(); glutDisplayFunc(mainWindowDisplay); // 在主窗口中指定函数mainWindowMouse,在鼠标按下或释放时将会被调用 glutMouseFunc(mainWindowMouse); // 创建子窗口 subWindow = glutCreateSubWindow(mainWindow, 0, 0, width / 4, height / 4); subWindowInit(); glutDisplayFunc(subWindowDisplay); // 在子窗口中指定函数subWindowKeyboard,当一个能够生成ASCII字符的键释放时会被调用 glutKeyboardFunc(subWindowKeyboard); // 输出帮助信息 printHelp(); glutMainLoop(); return 0; } ```
OpenGL 输入多个渲染缓存数据不一致的问题
我在示例代码中申请了一个帧缓存对象: ``` int FrameBuf; glGenFramebuffers(1, &FrameBuf); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FrameBuf); ``` 三个渲染缓存对象,第1个和第3个分别绑定为帧缓存对象的COLOR_ATTACHMENT0和COLOR_ATTACHMENT1,第2个绑定到帧缓存对象的DEPTH_ATTACHMENT: ``` glGenRenderbuffers(3, RendBuf); glBindRenderbuffer(GL_RENDERBUFFER, RendBuf[0]); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, 200, 200); glBindRenderbuffer(GL_RENDERBUFFER, RendBuf[1]); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 200, 200); glBindRenderbuffer(GL_RENDERBUFFER, RendBuf[2]); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, 200, 200); ``` 设置绑定点: ``` glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, RendBuf[0]); glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, RendBuf[1]); glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, RendBuf[2]); ``` 然后在绘制到帧缓存对象中: ``` glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FrameBuf); glViewport(0, 0, 200, 200); GLenum bufs[2] = { GL_COLOR_ATTACHMENT0 , GL_COLOR_ATTACHMENT1}; glDrawBuffers(2, bufs); glBindVertexArray(vert); glEnable(GL_DEPTH_TEST); glDrawArrays(GL_TRIANGLES, 0, 6); ``` 再将缓存中的数据写入显示窗口的缓存: ``` glBindFramebuffer(GL_READ_FRAMEBUFFER, FrameBuf); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glViewport(0, 0, 400, 400); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glReadBuffer(GL_COLOR_ATTACHMENT0); glBlitFramebuffer(0, 0, 200, 200, 0, 0, 200, 200, GL_COLOR_BUFFER_BIT, GL_NEAREST); glReadBuffer(GL_COLOR_ATTACHMENT1); glBlitFramebuffer(0, 0, 200, 200, 200, 0, 400, 200, GL_COLOR_BUFFER_BIT, GL_NEAREST); ``` 这是三角形的数据: ``` Vertex Verts[9] = { //第一个大三角形,三个顶点颜色分别为RGB,前四个float为颜色,后三个float为位置 { { 255,0,0,255 },{ 0.0f, 0.9f, 0.0f } }, { { 0,255,0,255 },{ -0.9f, -0.9f, 0.0f } }, { { 0,0,255,255 },{ 0.9f, -0.9f, 0.0f } } , //第二个小三角形,三个顶点颜色为白色 { { 255,255,255,255 },{ 0.0f, 0.8f, -0.2f } } , { { 255,255,255,255 },{ -0.4f, 0.0f, -0.2f } } , { { 255,255,255,255 },{ 0.4f, 0.0f, -0.2f } } }; ``` 以上就是画了两个小三角形,attachment0的在左下角,attachment1的在右下角。按理来说只调用了一次glDrawArrays(),两个三角形应该是一样的,但是真实的图片显示并不一样。这是为什么呢? ![图片说明](https://img-ask.csdn.net/upload/201911/28/1574911083_510881.png)
Win7采集摄像头数据显示图像回抖
开发环境:VS2015+qt5.7+相机驱动 实现方案:通过驱动配置回调函数,获取相机数据,然后把数据放入到数据缓冲区; 然后开启一个线程读取缓冲队列的数据,拷贝到一帧图像的缓冲块,并使用opengl(QOpenglWidget) 进行显示(updata()-onFrameSwapped()中emit render消息,次线程SLot进行显示)。 显示代码如下: void GLThreadWidget::UpdateShowImage() { update(); } void GLThreadWidget::onFrameSwapped() { m_renderer->unlockRenderer(); if (IsShowUpdateflag() == true) { emit renderRequested();//f发送消息 } } //槽函数 void Renderer::render() { if (m_exiting) return; bool needrender = m_glwidget->IsShowUpdateflag(); if (needrender == false) return; QImage * pimage = m_glwidget->GetCurImage(); if (pimage == nullptr) return; QOpenGLContext *ctx = m_glwidget->context(); if (!ctx) // QOpenGLWidget not yet initialized { m_glwidget->SetShowUpdateFlagFalse(); return; } if (ctx->thread() == QThread::currentThread()) { //qDebug() << "ctx->thread()" << ctx->thread(); m_glwidget->SetShowUpdateFlagFalse(); return; } // Grab the context. m_grabMutex.lock(); emit contextWanted(); m_grabCond.wait(&m_grabMutex); QMutexLocker lock(&m_renderMutex); m_grabMutex.unlock(); if (m_exiting) return; Q_ASSERT(ctx->thread() == QThread::currentThread()); // Make the context (and an offscreen surface) current for this thread. The // QOpenGLWidget's fbo is bound in the context. m_glwidget->makeCurrent(); if (!m_inited) { m_inited = true; initializeOpenGLFunctions(); initShaders(); initTextures(); initBuffArray(); } //initializeOpenGLFunctions(); GLfloat *pViewRect = m_glwidget->GetViewPortForRender(); glViewport(pViewRect[0], pViewRect[1], pViewRect[2], pViewRect[3]); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); // pimage = m_glwidget->GetCurImage(); int width; int height; m_glwidget->GetImageSize(width, height); m_texture->destroy(); m_texture->create(); m_texture->setSize(width, height); m_texture->setData((*pimage).mirrored()); m_program->bind(); m_texture->bind(); QMatrix4x4 m; this->m_program->setUniformValue(m_projviewUniform, m); this->m_program->setUniformValue(m_textureUniform, 0); // Draw cube geometry using indices from VBO 1 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); m_texture->release(); m_program->release(); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); // Make no context current on this thread and move the QOpenGLWidget's // context back to the gui thread. m_glwidget->doneCurrent(); ctx->moveToThread(qGuiApp->thread()); // Schedule composition. Note that this will use QueuedConnection, meaning // that update() will be invoked on the gui thread. QMetaObject::invokeMethod(m_glwidget, "update", Qt::QueuedConnection); m_glwidget->SetShowUpdateFlagFalse(); // qDebug() << "render finished"; } 方案结果:刚开始能够正常显示,当手在移动的时候,图像也能实时的进行移动。但是 过一段时间之后,图像出现回抖现象。 比如说,手在移动的时候,能看出来显示后面的一帧图像时,又显示了前一帧图像, 看到就是手往回移了一点然后又立马往前移动。 针对此问题怀疑是数据缓冲区对列乱了,但通过使用序号验证, 读取数据用于显示时,显示的序号都是从小到大的,没有出现变小的情况。 异常现象视频:http://v.youku.com/v_show/id_XMzI0MDg5NjYyNA==.html?spm=a2h3j.8428770.3416059.1 正常现象视频:http://v.youku.com/v_show/id_XMzI0MDg5Mzg3Ng==.html?spm=a2h3j.8428770.3416059.1
opengl 无法绘制大分辨率(6K)图像
写的opengl程序,发现以下现象。 1. 当图像的宽度/高度大于6K时,无法显示。 2. 但将图像在画图板中修改宽度/高度小于6K时,却能正确显示。 以下为主要核心代码,想知道是什么原因? ``` glGenTextures(1, m_nTexture); glBindTexture(GL_TEXTURE_2D, m_nTexture); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, iTextureWidth, iTextureHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pTextureData[0]); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glFlush(); glUseProgram(0); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); ```
使用OPENGLES2.0在安卓上如何实现增量点绘?
我在iOS上使用openGLES2.0实现了一个增量点绘的功能。 即我点击屏幕的某个位置,则在那个位置增加一个三角形。 我使用的是GLKView,在 -(void)glkView:(GLKView *)view drawInRect:(CGRect)rect; 里调用如下方法 (不clear) glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(LineVertex), &vertices[0].pos); glEnableVertexAttribArray(GLKVertexAttribColor); glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(LineVertex), &vertices[0].color); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)count); 得到的结果是正确的。(每次点击屏幕就多一个三角形) 我在安卓做了一样的实现。 在 public void onDrawFrame(GL10 unused) 里调用了如下方法(同样不clear) GLES20.glEnableVertexAttribArray(mPositionHandle); GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 7*Float.SIZE/8, verticesBuffer.position(0)); GLES20.glEnableVertexAttribArray(mColorHandle); GLES20.glVertexAttribPointer(mColorHandle, 4, GLES20.GL_FLOAT, false, 7*Float.SIZE/8, verticesBuffer.position(3)); GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, mtrxProjectionAndView, 0); GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, count); 结果就是,每次进入onDrawFrame方法调用glDrawArrays时都会把之前的绘图结果清掉,然后画一个三角形,即永远只有1个三角形。我并没有调用clear。想请教下高手如何能够使用OPENGLES在安卓上实现增量点绘?是否我需要设置某些参数才能够每次渲染新的三角形之前不会删除旧的内容?为什么iOS下的实现和安卓上实现时,基本相同的代码会有不同的结果?我也试过每次glDrawArrays(android上)之前把都把本次绘图和历史绘图结果存成一个新的历史缓冲区,后面每次onDrawFrame都先画一次历史缓冲区的内容,但很快缓冲区就爆了。
请求大神帮帮我~~~~~~~~~~~游戏代码
一个用cocos做的游戏,游戏中需要用到网格,但是一运行代码就出现中断错误卡在下面这几行: glVertexAttribPointer(kCCVertexAttrib_Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, kQuadSize, (void*)(offset + diff)); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); CHECK_GL_ERROR_DEBUG(); 提示的错误是这样的:0x699AC32E (nvoglv32.dll) (HelloCpp.exe 中)处有未经处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突。 想问下怎么解决~~
Opengl中ProcessMouseScroll(GLfloat yOffset)函数不起作用
鼠标滚轮不起作用,不会报错,不知道是怎么回事 主函数如下: ``` #include <iostream> #define GLEW_STATIC #include <GL/glew.h> #include <GLFW/glfw3.h> #include "Shader.h" #include "Camera.h" #include "Light.h" #include <glm/glm.hpp> #include <glm/gtc/type_ptr.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtx/rotate_vector.hpp> void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mode); void MouseCallback(GLFWwindow *window, double xPos, double yPos); void ScrollCallback(GLFWwindow *window, double xOffset, double yOffset); void DoMovement(); bool keys[1024]; const GLint WIDTH = 800, HEIGHT = 600; Camera camera(glm::vec3(0.0f, 0.0f, 2.0f)); GLfloat deltaTime = 0.0f; GLfloat lastTime = 0.0f; GLfloat lastX = WIDTH / 2; GLfloat lastY = HEIGHT / 2; bool firstMouse = true; glm::vec3 lightPos = glm::vec3(0.0f, 0.0f, 0.0f); int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); GLFWwindow * window = glfwCreateWindow(WIDTH, HEIGHT, "w11", nullptr, nullptr); if (nullptr == window) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); glfwSetKeyCallback(window, KeyCallback); glfwSetCursorPosCallback(window, MouseCallback); glfwSetScrollCallback(window, ScrollCallback); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); int screenWidth, screenHeight; glfwGetFramebufferSize(window, &screenWidth, &screenHeight); glewExperimental = GL_TRUE; if (GLEW_OK != glewInit()) { std::cout << "Failed to initialise GLEW" << std::endl; glfwTerminate(); return -1; } Shader lightShader = Shader("res/shaders/light.vs", "res/shaders/light.frag"); Light lightModel = Light(); Shader shader = Shader("res/shaders/core.vs", "res/shaders/core.frag"); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); GLfloat vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f }; GLuint VAO, VBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); // transfer the data glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // set the attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid *)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid *)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); glm::mat4 view = glm::mat4(1.0f); //glm::mat4 projection = glm::perspective(glm::radians(camera.GetZoom()), static_cast<GLfloat>(screenWidth) / static_cast<GLfloat>(screenHeight), 0.1f, 1000.0f); glm::mat4 projection = glm::perspective(camera.GetZoom(), (float)screenWidth / (float)screenHeight, 0.1f, 100.0f); while (!glfwWindowShouldClose(window)) { GLfloat currentTime = glfwGetTime(); deltaTime = currentTime - lastTime; lastTime = currentTime; glfwPollEvents(); DoMovement(); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, screenWidth, screenHeight); view = camera.GetViewMatrix(); glm::mat4 transform = glm::mat4(1.0f); lightShader.Use(); lightPos = glm::vec3(20.0f, 0.0f, 0.0f); lightPos = glm::rotate(lightPos, glm::radians(20.0f)*static_cast<GLfloat>(glfwGetTime()), glm::vec3(1.0f, 1.0f, 1.0f)); transform = glm::scale(transform, glm::vec3(0.1f, 0.1f, 0.1f)); transform = glm::translate(transform, lightPos); glUniformMatrix4fv(glGetUniformLocation(lightShader.Program, "model"), 1, GL_FALSE, glm::value_ptr(transform)); glUniformMatrix4fv(glGetUniformLocation(lightShader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view)); glUniformMatrix4fv(glGetUniformLocation(lightShader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection)); lightModel.Draw(lightShader); shader.Use(); transform = glm::mat4(1.0f); transform = glm::scale(transform, glm::vec3(0.4f, 0.4f, 0.4f)); GLuint transLoc = glGetUniformLocation(shader.Program, "model"); glUniformMatrix4fv(transLoc, 1, GL_FALSE, glm::value_ptr(transform)); GLuint viewLoc = glGetUniformLocation(shader.Program, "view"); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); GLuint projLoc = glGetUniformLocation(shader.Program, "projection"); glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); glUniform3f(glGetUniformLocation(shader.Program, "LightPos"), lightPos.x, lightPos.y, lightPos.z); glUniform3f(glGetUniformLocation(shader.Program, "ViewPos"), camera.GetPosition().x, camera.GetPosition().y, camera.GetPosition().z); glUniform1f(glGetUniformLocation(shader.Program, "p"), 64.0f); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 36); glBindVertexArray(0); glfwSwapBuffers(window); } glfwTerminate(); return 0; } void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mode) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { glfwSetWindowShouldClose(window, GL_TRUE); } if (key >= 0 & key < 1024) { if (action == GLFW_PRESS) { keys[key] = true; } else if (action == GLFW_RELEASE) { keys[key] = false; } } } void DoMovement() { if (keys[GLFW_KEY_W] || keys[GLFW_KEY_UP]) { camera.ProcessKeyboard(FORWARD, deltaTime); } if (keys[GLFW_KEY_S] || keys[GLFW_KEY_DOWN]) { camera.ProcessKeyboard(BACKWARD, deltaTime); } if (keys[GLFW_KEY_A] || keys[GLFW_KEY_LEFT]) { camera.ProcessKeyboard(LEFT, deltaTime); } if (keys[GLFW_KEY_D] || keys[GLFW_KEY_RIGHT]) { camera.ProcessKeyboard(RIGHT, deltaTime); } } void MouseCallback(GLFWwindow *window, double xPos, double yPos) { if (firstMouse) { lastX = xPos; lastY = yPos; firstMouse = false; } GLfloat xOffset = xPos - lastX; GLfloat yOffset = yPos - lastY; lastX = xPos; lastY = yPos; camera.ProcessMouseMovement(xOffset, yOffset); } void ScrollCallback(GLFWwindow* window, double xOffset, double yOffset) { camera.ProcessMouseScroll(yOffset); } ``` Camera.h如下: ``` #pragma once #define GLEW_STATIC #include <GL/glew.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <vector> enum Camera_Movement { FORWARD, BACKWARD, LEFT, RIGHT }; const GLfloat YAW = -90.0f; const GLfloat PITCH = 0.0f; const GLfloat SPEED = 6.0f; const GLfloat SENSITIVITY = 0.25f; const GLfloat ZOOM = 45.0f; class Camera { public: Camera(glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f), GLfloat yaw = YAW, GLfloat pitch = PITCH) :front(glm::vec3(0.0f, 0.0f, -1.0f)), movementSpeed(SPEED), mouseSensitivity(SENSITIVITY), zoom(ZOOM) { this->position = position; this->worldUp = up; this->yaw = yaw; this->pitch = pitch; this->updateCameraVectors(); } Camera(GLfloat posX, GLfloat posY, GLfloat posZ, GLfloat upX, GLfloat upY, GLfloat upZ, GLfloat yaw = YAW, GLfloat pitch = PITCH) :front(glm::vec3(0.0f, 0.0f, -1.0f)), movementSpeed(SPEED), mouseSensitivity(SENSITIVITY), zoom(ZOOM) { this->position = glm::vec3(posX, posY, posZ); this->worldUp = glm::vec3(upX, upY, upZ); this->yaw = yaw; this->pitch = pitch; this->updateCameraVectors(); } void ProcessKeyboard(Camera_Movement direction, GLfloat deltaTime) { GLfloat velocity = this->movementSpeed * deltaTime; if (direction == FORWARD) { this->position += this->front * velocity; } if (direction == BACKWARD) { this->position -= this->front * velocity; } if (direction == LEFT) { this->position -= this->right * velocity; } if (direction == RIGHT) { this->position += this->right * velocity; } } void ProcessMouseMovement(GLfloat xOffset, GLfloat yOffset, GLboolean constrainPitch = true) { xOffset *= this->mouseSensitivity; yOffset *= this->mouseSensitivity; this->yaw += xOffset; this->pitch -= yOffset; if (constrainPitch) { if (this->pitch > 89.0f) { this->pitch = 89.0f; } if (this->pitch < -89.0f) { this->pitch = -89.0f; } } updateCameraVectors(); } glm::mat4 GetViewMatrix() { return glm::lookAt(this->position, this->position + this->front, this->up); } void ProcessMouseScroll(GLfloat yOffset) { if (this->zoom >= 1.0f && this->zoom <= 45.0f) { this->zoom -= yOffset ; } if (this->zoom <= 1.0f) { this->zoom = 1.0f; } if (this->zoom >= 45.0f) { this->zoom = 45.0f; } } GLfloat GetZoom() { return this->zoom; } glm::vec3 GetPosition() { return this->position; } private: glm::vec3 position; glm::vec3 front; glm::vec3 up; glm::vec3 right; glm::vec3 worldUp; GLfloat yaw; GLfloat pitch; GLfloat movementSpeed; GLfloat mouseSensitivity; GLfloat zoom; void updateCameraVectors() { glm::vec3 front; front.x = cos(glm::radians(this->pitch))*cos(glm::radians(this->yaw)); front.y = sin(glm::radians(this->pitch)); front.z = cos(glm::radians(this->pitch))*sin(glm::radians(this->yaw)); this->front = glm::normalize(front); this->right = glm::normalize(glm::cross(this->front, this->worldUp)); this->up = glm::normalize(glm::cross(this->right, this->front)); } }; ``` 求大佬讲解
opengl android,为什么我的三角形不显示都是照着写的我的render哪里写错了吗
package com.cheerchip.opengl5; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.opengl.Matrix; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; /** * Created by noname on 2017/6/28. */ public class GLRender implements GLSurfaceView.Renderer { //顶点颜色 private final String vertexShaderCode = "attribute vec4 vPosition;" + "void main() {" + " gl_Position = vPosition;" + "}"; //片元颜色 private final String fragmentShaderCode = "precision mediump float;" + "uniform vec4 vColor;" + "void main() {" + " gl_FragColor = vColor;" + "}"; private int programs; //三角形顶点 private float[] vertexes = new float[]{ 1f, 0f, 0f, 0f, 1f, 0f, -1f, 0f, 0f }; private FloatBuffer floatBuffer; @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { GLES20.glClearColor(0.5f,0.5f,0.5f,1.0f);//设置背景色灰色 init(); //生成shader调色板 //顶点和片元一般两种 int verextype = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER); GLES20.glShaderSource(verextype, vertexShaderCode); GLES20.glCompileShader(verextype); int fragmenttype = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER); GLES20.glShaderSource(fragmenttype, fragmentShaderCode); GLES20.glCompileShader(fragmenttype); // GLES20. programs = GLES20.glCreateProgram(); //连接到调色板 GLES20.glAttachShader(programs, verextype); GLES20.glAttachShader(programs, fragmenttype); //连接programs GLES20.glLinkProgram(programs); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { GLES20.glViewport(0,0,width,height); float ratio = (float) width / height; // create a projection matrix from device screen geometry //Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7); } @Override public void onDrawFrame(GL10 gl) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT); GLES20.glUseProgram(programs); //获取顶点着色器的vPosition成员句柄 int mPositionHandle = GLES20.glGetAttribLocation(programs, "vPositon"); //启用三角形顶点的句柄 GLES20.glEnableVertexAttribArray(mPositionHandle); //准备三角形数据3*4顶点偏移量 GLES20.glVertexAttribPointer(mPositionHandle,3,GLES20.GL_FLOAT,false,3*4,floatBuffer); int uniformhandle= GLES20.glGetUniformLocation(programs,"vColor"); //绘制颜色 GLES20.glUniform4fv(uniformhandle,1,color,0); //h绘制图像 GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,3); GLES20.glDisableVertexAttribArray(mPositionHandle); } //设置颜色,依次为红绿蓝和透明通道 float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; // 准备数据 private void init(){ ByteBuffer buffer=ByteBuffer.allocateDirect(vertexes.length*4);//每个数4个字节 buffer.order(ByteOrder.nativeOrder()); floatBuffer = buffer.asFloatBuffer(); floatBuffer.put(vertexes); floatBuffer.position(0); } }
请教 安卓 opengl es 如何能后画出带有渐变色的线段。。
网上看到了画线段了例子但是都不知道,把那段代码放在项目的什么地方。。。 网上看到的代码贴出来。。。 float vertexArray[] = { -0.8f, -0.4f * 1.732f, 0.0f, -0.4f, 0.4f * 1.732f, 0.0f, 0.0f, -0.4f * 1.732f, 0.0f, 0.4f, 0.4f * 1.732f, 0.0f, }; public void DrawScene(GL10 gl) { super.DrawScene(gl); ByteBuffer vbb = ByteBuffer.allocateDirect(vertexArray.length*4); vbb.order(ByteOrder.nativeOrder()); FloatBuffer vertex = vbb.asFloatBuffer(); vertex.put(vertexArray); vertex.position(0); gl.glLoadIdentity(); gl.glTranslatef(0, 0, -4); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex); index++; index%=10; switch(index){ case 0: case 1: case 2: gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f); gl.glDrawArrays(GL10.GL_LINES, 0, 4); break; case 3: case 4: case 5: gl.glColor4f(0.0f, 1.0f, 0.0f, 1.0f); gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, 4); break; case 6: case 7: case 8: case 9: gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f); gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4); break; } gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); }
关于opengl帧缓存对象FBO深度缓存的问题
各位老师好,在下opengl菜鸟一枚,最近学习opengl和glsl的过程中,使用FBO的深度缓存做延时渲染的时候遇到了一些问题。 我想实现个shadowmap,在光源视角下将深度缓存渲染进fbo,但是渲染第一次结束后,附加到fbo中的深度纹理里面的值却全部都为0。后来为了测试问题,我删除掉了第二个shader,只保留了第一个用来产生shadowmap的shader,发现fbo深度缓存依然都是0。如能指教迷津,不胜感激。一下是我的代码: main函数 ``` #include <stdio.h> #include "Declaration.h" #include "LoadShaders.h" #include <gl/glew.h> #include <gl/freeglut.h> #include "cv.h" #include "highgui.h" #include "cxcore.h" #include "StructDef.h" GLuint *FBOUsedVAOs; GLuint *FBOUsedBuffers; GLuint *programs; GLuint *FBOs; GLuint *DepthTextureIDs; void init() { DepthTextureIDs = (GLuint*)malloc(sizeof(GLuint));//申请深度纹理对象ID的内存 glGenTextures(1, DepthTextureIDs);//产生深度纹理ID glBindTexture(GL_TEXTURE_2D, DepthTextureIDs[0]);//绑定深度纹理ID //设置纹理参数 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 512, 512, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glBindTexture(GL_TEXTURE_2D, 0);//解绑纹理ID FBOs = (GLuint*)malloc(sizeof(GLuint));//申请帧缓存对象的内存 glGenFramebuffers(1,FBOs);//产生帧缓存对象 glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0]);//绑定帧缓存对象 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, DepthTextureIDs[0], 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); glBindFramebuffer(GL_FRAMEBUFFER, 0);//解绑帧缓存对象 programs = (GLuint*)malloc(sizeof(GLuint));//申请着色程序内存 ShaderInfo FBOShader[3] = { //用于渲染shadowmap的着色器 { GL_VERTEX_SHADER, "FBOShader.vert" }, { GL_FRAGMENT_SHADER, "FBOShader.frag" }, { GL_NONE, NULL } }; programs[0] = LoadShaders(FBOShader); //加载着色器 //计算各种坐标转换矩阵 float ModelMat[16]; float ViewMat[16]; float PerspectiveProjectMat[16]; float MAngle321[3] = {0, 0, 0.0}; float MOffset[3] = {0.0, 0.0, 0.0}; float VAngle321[3] = {0, 1.57, 0.0}; float VOffset[3] = {0, 0, 5.0}; float FOV = 1.57; float Aspect = 1; float NearDist = 1.0; float FarDist = 6; ModelMatCal(ModelMat, MAngle321, MOffset); ViewMatCal(ViewMat, VAngle321, VOffset); PerspectiveProjectMatCal(PerspectiveProjectMat, FOV, Aspect, NearDist, FarDist); float MVMat[16]; float MVPMat[16]; MatMultiplyMat4(MVMat, ViewMat, ModelMat); MatMultiplyMat4(MVPMat, PerspectiveProjectMat, MVMat); //将矩阵传递进FBOShader glUseProgram(programs[0]);//必须放在向shader中传Uniform数据的前面 GLint MVPMatLoc; MVPMatLoc = glGetUniformLocation(programs[0],"MVPMat"); glUniformMatrix4fv(MVPMatLoc, 1, GL_FALSE, MVPMat); //设置顶点数组 #define BUFFER_OFFSET(offset) ((void *)(NULL+offset)) FBOUsedVAOs = (GLuint*)malloc(sizeof(GLuint)); FBOUsedBuffers = (GLuint*)malloc(sizeof(GLuint)); glGenVertexArrays(1, FBOUsedVAOs); glGenBuffers(1, FBOUsedBuffers); float FBOUsedVertices[24]= { 1.0f, 1.0f, 3.0f, 1.0f, -1.0f, 1.0f, 3.0f, 1.0f, -1.0f, -1.0f, 3.0f, 1.0f, 1.0f, 1.0f, 3.0f, 1.0f, -1.0f, -1.0f, 3.0f, 1.0f, 1.0f, -1.0f, 3.0f, 1.0f }; glBindVertexArray(FBOUsedVAOs[0]); glBindBuffer(GL_ARRAY_BUFFER, FBOUsedBuffers[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(FBOUsedVertices), FBOUsedVertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); glEnableVertexAttribArray(0); } void display() { //向帧缓存对象中渲染数据 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0]);//绑定帧缓存对象 glUseProgram(programs[0]);//选定shader glBindVertexArray(FBOUsedVAOs[0]); glDrawArrays(GL_TRIANGLES, 0, 6); float *DepthPixel = (float *)malloc(sizeof(float)); glReadPixels(256,256,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,DepthPixel); glBindFramebuffer(GL_FRAMEBUFFER, 0); glFlush(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutInitWindowSize(512, 512); glutInitContextVersion(4, 3); glutInitContextProfile(GLUT_CORE_PROFILE); glutCreateWindow(argv[0]); glewExperimental = GL_TRUE; if (glewInit()) { cerr << "Unable to initialize GLEW ... exiting" << endl; exit(1); } glEnable(GL_TEXTURE_CUBE_MAP); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); init(); glutDisplayFunc(display); glutMainLoop(); } ``` 顶点着色器 ``` #version 430 layout(location = 0)in vec4 VertPosition; uniform mat4 MVPMat; void main() { gl_Position = MVPMat * VertPosition; } ``` 片元着色器 ``` #version 430 out vec4 FragColor; void main() { FragColor = vec4(vec3(gl_FragCoord.z), 1.0f); } ``` 将display函数中的glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0])注释掉,就能够在DepthPixel中看到正确的深度结果,但是只要绑定了fbo,其深度结果就全都是0.也就是说,在屏渲染的时候,我能够获取到正确的深度值,但是离屏渲染的时候,深度值总是0.
关于OpenGL用shader来使用贴图的一些问题
我想实现用shader来显示贴图,但是总是没办法显示图片,只能显示一个灰色的三角形,希望有人能帮我看看是什么问题,下面是代码 void initTest(char* fileName1, char* fileName2) { Shader shader("D:\\VS2013Project\\CPP_Project\\subdivision\\subdivision\\Shader\\shaderTextureTest"); shader.Bind(); currentShader = shader.GetProgram(); tex_model_view_matrix_loc = glGetUniformLocation(shader.GetProgram(), "model_view_matrix"); tex_projection_matrix_loc = glGetUniformLocation(shader.GetProgram(), "projection_matrix"); tex_sampler_texture_unit = glGetUniformLocation(shader.GetProgram(), "tex"); int imageWidth1, imageHeight1; FREE_IMAGE_FORMAT fif1 = FreeImage_GetFileType(fileName1); FIBITMAP* dib1 = FreeImage_Load(fif1, fileName1, 0); if (dib1 == NULL) return; dib1 = FreeImage_ConvertTo24Bits(dib1); BYTE* image1Data; imageWidth1 = FreeImage_GetWidth(dib1); imageHeight1 = FreeImage_GetHeight(dib1); image1Data = FreeImage_GetBits(dib1); static const GLfloat vertex_array[] = { 0.0f, 0.0f, 0.0f, 1.0f, 10.0f, 0.0f, 0.0f, 1.0f, 0.0f, 10.0f, 0.0f, 1.0f, 10.0f, 10.0f, 0.0f, 1.0f }; static const GLfloat tex_coord_array[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; //glActiveTexture(GL_TEXTURE1); //以下是处理顶点数据和纹理坐标数据的代码 glGenBuffers(1, textureVertexDataBuffer); glBindBuffer(GL_ARRAY_BUFFER, textureVertexDataBuffer[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_array) + sizeof(tex_coord_array), NULL, GL_STATIC_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertex_array), vertex_array); glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertex_array), sizeof(tex_coord_array), tex_coord_array); glGenVertexArrays(1, textureVAO); glBindVertexArray(textureVAO[0]); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (void*)(0)); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)(vertex_array)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glGenTextures(1, textureBuffer); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureBuffer[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth1, imageHeight1, 0, GL_RGB, GL_UNSIGNED_BYTE, image1Data); glUniform1i(tex_sampler_texture_unit, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(currentShader); vmath::mat4 projection_matrix(vmath::perspective(45, aspect, 0.1, 100)); vmath::vecN<float, 3> eye; eye[0] = 0.0f; eye[1] = 0.0f; eye[2] = 6.0f; vmath::vecN<float, 3> center; center[0] = 0.0f; center[1] = 0.0f; center[2] = 0.0f; vmath::vecN<float, 3> up; up[0] = 0.0f; up[1] = 1.0f; up[2] = 0.0f; vmath::mat4 modelView_matrix(vmath::lookat(eye, center, up)); glUniformMatrix4fv(tex_model_view_matrix_loc, 1, GL_FALSE, modelView_matrix); glUniformMatrix4fv(tex_projection_matrix_loc, 1, GL_FALSE, projection_matrix); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureBuffer[0]); glBindVertexArray(textureVAO[0]); glDrawArrays(GL_TRIANGLES, 0, 3); glutSwapBuffers(); } 下面是shader的代码: vert: #version 430 core layout (location = 0) in vec4 vertex_position; layout (location = 1) in vec2 texture_coord; uniform mat4 model_view_matrix; uniform mat4 projection_matrix; out vec2 output_tex_coord; void main() { gl_Position = projection_matrix * model_view_matrix * vertex_position; output_tex_coord = texture_coord; } frag: #version 430 core uniform sampler2D tex; layout (location = 0) out vec4 color; in vec2 output_tex_coord; void main() { color = texture(tex, output_tex_coord); } 下面是结果 ![图片说明](https://img-ask.csdn.net/upload/201706/04/1496571190_821232.png)
新人求教,OPENGL的几个简单问题
要求在OPENGL里绘制一个彩色的三角形,颜色可随时间变换。 ``` #include <iostream> // GLEW #define GLEW_STATIC #include <GL/glew.h> // GLFW #include <GLFW/glfw3.h> // Function prototypes void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode); // Window dimensions const GLuint WIDTH = 800, HEIGHT = 600; // Shaders const GLchar* vertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 position;\n" "layout (location = 1) in vec3 color;\n" "out vec3 ourColor;\n" "void main()\n" "{\n" "gl_Position = vec4(position, 1.0);\n" "ourColor = color;\n" "}\0"; const GLchar* fragmentShaderSource = "#version 330 core\n" "in vec3 ourColor;\n" "out vec4 color;\n" "void main()\n" "{\n" "color = vec4(ourColor, 1.0f);\n" "}\n\0"; // The MAIN function, from here we start the application and run the game loop int main() { // Init GLFW glfwInit(); // Set all the required options for GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr); glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers glewInit(); // Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT); // Build and compile our shader program // Vertex shader GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); // Check for compile time errors GLint success; GLchar infoLog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; } // Fragment shader GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); // Check for compile time errors glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; } // Link shaders GLuint shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); // Check for linking errors glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); // Set up vertex data (and buffer(s)) and attribute pointers GLfloat vertices[] = { // Positions // Colors 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Right -0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // Bottom Left 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // Top }; GLuint VBO, VAO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // Color attribute glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glBindVertexArray(0); // Unbind VAO // Game loop while (!glfwWindowShouldClose(window)) { // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); // Render // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // Draw the triangle glUseProgram(shaderProgram); glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray(0); // Swap the screen buffers glfwSwapBuffers(window); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate(); return 0; } // Is called whenever a key is pressed/released via GLFW void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) glfwSetWindowShouldClose(window, GL_TRUE); } ``` 以上是彩色三角形的代码,那么要如何实现颜色随时间的变换呢?
简单的OpenGL问题,大佬们帮一把!
如题,最近在学OpenGL。今天自己写了一个画三角形的程序,但是,出来的结果不对,坐标和我设置的不一样。于是我就试着画了两条垂直的直线,结果还是不对。 具体情况看下图:我想要画(-1,0)(1,0)(0,-1)(0,1)两条直线,结果如下: ![图片说明](https://img-ask.csdn.net/upload/201707/19/1500453644_632145.png) 代码如下: ```#include<glad/glad.h> #include<gl/glfw3.h> #include<iostream> #pragma comment(lib,"glfw3.lib") using namespace std; void framebuffer_size_callback(GLFWwindow * window,int width,int height); void processInput(GLFWwindow *window); //定义顶点着色器 const char *VertexShaderSource = "#version 430 core\n" "layout(location=0) in vec3 aPos;\n" "void main()\n" "{\n" "gl_Position=vec4(aPos.x,aPos.y,aPos.z,1.0);\n" "}\n\0"; //定义片元着色器 const char *FragmentShaderSource = "#version 430 core\n" "out vec4 FragColor;\n" "void main()\n" "{\n" "FragColor=vec4(1.0,0.5,0.2,1.0);" "}\n\0"; int main() { glfwInit();//初始化GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);//配置GLFW:想要配置什么选项:指定OpenGL最低主版本号 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);//指定OpenGL最低副版本号 glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);//指定使用OpenGL库 GLFWwindow * window = glfwCreateWindow(600,600,"LearnOpenGL",NULL,NULL);//创建窗口(该函数返回一个GLFWwindow对象) //参数:第一二个参数指定窗口的宽和高, //第三个指定窗口名称。最后两个参数可以忽略 if (window==NULL) { cout << "Failed to create GLFW window" << endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { cout << "Failed to initialize GLAD" << endl; return -1; } //初始化顶点着色器 int vertexShader=glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader,1,&VertexShaderSource,NULL); glCompileShader(vertexShader); int success; char infoLog[512]; glGetShaderiv(vertexShader,GL_COMPILE_STATUS,&success); if (!success) { glGetShaderInfoLog(vertexShader,512,NULL,infoLog); cout << "Failed to compile vertexshader"<<endl; } //初始化片元着色器 int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader,1,&FragmentShaderSource,NULL); glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderSource(fragmentShader,512,NULL,infoLog); cout << "Failed to compile fragment shader" << endl; } //定义并初始化Shader Programe int programe = glCreateProgram(); glAttachShader(programe,vertexShader); glAttachShader(programe,fragmentShader); glLinkProgram(programe); glGetProgramiv(programe,GL_LINK_STATUS,&success); if (!success) { glGetProgramInfoLog(programe,512,NULL,infoLog); cout << "Failed to Link Programe" << endl; } glValidateProgram(programe); glGetProgramiv(programe,GL_VALIDATE_STATUS,&success); if (!success) { glGetProgramInfoLog(programe,512,NULL,infoLog); cout<<"Failed to validate programe"<<endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); glUseProgram(programe); //定义顶点数组 float vertex[] = { -1.0,0.0, 1.0,0.0, 0.0,-1.0, 0.0,1.0 }; //定义VBO,VAO unsigned int VBO,VAO; glGenVertexArrays(1,&VAO); glGenBuffers(1,&VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER,VBO); glBufferData(GL_ARRAY_BUFFER,sizeof(vertex),vertex,GL_STATIC_DRAW); glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(float),(void*)0); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER,0); glBindVertexArray(0); glViewport(0,0,600,600); glfwSetFramebufferSizeCallback(window,framebuffer_size_callback); //指定窗口尺寸改变时所使用的回调函数 while (!glfwWindowShouldClose(window)) //当我们告知GLFW结束时,在关闭窗口 { processInput(window); glClearColor(0.2,0.3,0.3,1.0); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(programe); glBindVertexArray(VAO); glDrawArrays(GL_LINES,0,4); glfwSwapBuffers(window); glfwPollEvents(); //检查是否有事件触发(如输入或者鼠标移动操作),然后 //更新窗口状态 } glDeleteVertexArrays(1,&VAO); //绘制结束之后销毁所有的VAO与VBO glDeleteBuffers(1,&VBO); glfwTerminate(); return 0; } void framebuffer_size_callback(GLFWwindow* window,int width,int height) //改变窗口大小的回调函数 { glViewport(0,0,width,height); } void processInput(GLFWwindow * window) { if ((glfwGetKey(window,GLFW_KEY_BACKSPACE)==GLFW_PRESS)) { glfwSetWindowShouldClose(window,true); } } ```
QOpenglWidget中使用glortho无法绘制出纹理图,在glut下可以
在QOpenglWidget中绘制图形,使用glm::ortho模式进行正交投影,发现图形无法显示。如下图所示,显示的是清屏的红色。 ![图片说明](https://img-ask.csdn.net/upload/201708/02/1501657156_246266.jpg) 相同的绘制代码使用glut绘制的窗体中,可以正常显示。如下图所示。 ![图片说明](https://img-ask.csdn.net/upload/201708/02/1501657223_321489.jpg) 以下贴出核心代码,请问可能什么原因? const GLfloat vertexVertices[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f }; const GLfloat textureVertices[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, }; void HozoHorizontalDrawer::InitDrawer() { InitShader();//加载shader source GenTextureArray();//创建纹理 glUniform1i(m_iYTextureUniform, 0); SetTextureEnvInitFlag(true); glUseProgram(m_nShaderProgram); glGenBuffers(2, m_nBufferArray); glBindBuffer(GL_ARRAY_BUFFER, m_nBufferArray[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexVertices), vertexVertices, GL_STATIC_DRAW); glVertexAttribPointer(eVertex, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); glEnableVertexAttribArray(eVertex); glBindBuffer(GL_ARRAY_BUFFER, m_nBufferArray[1]); glBufferData(GL_ARRAY_BUFFER, sizeof(textureVertices), textureVertices, GL_STATIC_DRAW); glVertexAttribPointer(eTexture, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); glEnableVertexAttribArray(eTexture); } void HozoHorizontalDrawer::Draw(float PlayerControlWidth, float PlayerControlHeight, tagTextureDescription panoramaFrame) { glClearColor(1.0f, 0.0f, 0.0f, 1.0f); glClearDepth(1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glShadeModel(GL_SMOOTH); glUseProgram(m_nShaderProgram); //正交投影 m_mat4View = glm::lookAt(glm::vec3(0, 0, -1), glm::vec3(0, 0, 0), glm::vec3(0, -1, 0)); m_mat4Projection = glm::ortho(-1.0f, 1.0f, -1.0f, 1.0f); m_mat4Model = glm::mat4(1.0f); m_mat4Model = glm::translate(m_mat4Model, glm::vec3(m_fXTranslate, m_fYTranslate, m_fZTranslate)); m_mat4Model = glm::rotate(m_mat4Model, glm::radians(m_fXRotateDegree), glm::vec3(1.0f, 0, 0)); m_mat4Model = glm::rotate(m_mat4Model, glm::radians(m_fYRotateDegree), glm::vec3(0, 1.0f, 0)); m_mat4Model = glm::rotate(m_mat4Model, glm::radians(m_fZRotateDegree), glm::vec3(0, 0, 1.0f)); m_mat4Model = glm::scale(m_mat4Model, glm::vec3(m_fXScale, m_fYScale, m_fZScale)); m_mat4ProjectionModelView = m_mat4Projection * m_mat4View * m_mat4Model; glUniformMatrix4fv(m_iProjectionModelViewIDUniform, 1, GL_FALSE, &m_mat4ProjectionModelView[0][0]); glEnable(GL_TEXTURE_2D); SetTexturesImages(panoramaFrame); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glFlush(); glUseProgram(0); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); } 对应QOpenGLWidget代码如下。 void QMyOpenGLWidget::initializeGL() { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->initializeOpenGLFunctions(); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); } void QMyOpenGLWidget::resizeGL(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); } void QMyOpenGLWidget::paintGL() { makeCurrent(); if (nullptr != m_Picture.pTextureData[0] && nullptr != m_pDrawer) { this->m_pDrawer->Draw(this->width(), this->height(), m_Picture); } } void QMyOpenGLWidget::drawPicturepaintGL() { this->update(); return; } 对应顶点着色器和片段着色器代码如下。 #version 330 core uniform mat4 ProjectionModelView; attribute vec4 vertexCoord; attribute vec2 textureCoord; varying vec2 outTextureCoord; void main(void){ gl_Position = ProjectionModelView * vertexCoord; outTextureCoord = textureCoord; } varying vec2 outTextureCoord; uniform sampler2D textureY; void main(void) { vec3 bgr; bgr = texture2D(textureY, outTextureCoord).rgb; gl_FragColor = vec4(bgr, 1.0); }
为什么我开了gl_depth_test先绘制的图形还是会被后绘制的图形覆盖?
#import "ViewController.h" #import "sphere.h" typedef struct { GLKVector3 position; GLKVector3 normal; GLKVector4 color; }SceneVertex; SceneVertex vertex[3888]; @interface ViewController () @property(nonatomic,assign)GLuint program; @property(nonatomic,assign)GLint modelMat; @property(nonatomic,assign)GLint viewMat; @property(nonatomic,assign)GLint projectionMat; @property(nonatomic,assign)GLint tex; @property(nonatomic,assign)GLint color; @end @implementation ViewController { GLKMatrix4 modelMatrix; GLKMatrix4 viewMatrix; GLKMatrix4 projectionMatrix; GLuint earth; GLuint moon; GLuint tx[2]; GLKMatrix4 moonMatrix; GLfloat moonDepth; } - (void)viewDidLoad { [super viewDidLoad]; //初始化绘图上下文 moonDepth = 0.0f; GLKView *view = (GLKView *)self.view; view.context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2]; [EAGLContext setCurrentContext:view.context]; view.drawableDepthFormat = GLKViewDrawableDepthFormat16; //初始化绘图上下文 for (int i=0; i<1944; i++) { vertex[i].position.x = sphereVerts[3*i]; vertex[i].position.y = sphereVerts[3*i+1]; vertex[i].position.z = sphereVerts[3*i+2]; vertex[i].color = GLKVector4Make(1, 1, 1, 1); vertex[i].normal.x = sphereNormals[3*i]; vertex[i].normal.y = sphereNormals[3*i+1]; vertex[i].normal.z = sphereNormals[3*i+2]; } for (int i=0; i<1944; i++) { vertex[i+1944].position.x = sphereVerts[3*i]+0.3; vertex[i+1944].position.y = sphereVerts[3*i+1]; vertex[i+1944].position.z = sphereVerts[3*i+2]; vertex[i+1944].normal.x = sphereNormals[3*i]; vertex[i+1944].normal.y = sphereNormals[3*i+1]; vertex[i+1944].normal.z = sphereNormals[3*i+2]; vertex[i+1944].color = GLKVector4Make(1, 0.5, 1, 1); } glEnable(GL_CULL_FACE|GL_DEPTH_TEST); glClearColor(0, 0, 0, 1); glGenBuffers(1, &earth); glBindBuffer(GL_ARRAY_BUFFER, earth); ssize_t number = sizeof(vertex) / sizeof(SceneVertex); NSLog(@"%li",number); glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL); glEnableVertexAttribArray(GLKVertexAttribColor); glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, 0, sizeof(SceneVertex), NULL+offsetof(SceneVertex, color)); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL+offsetof(SceneVertex, normal)); glBindBuffer(GL_ARRAY_BUFFER, 0); [self loadShaders]; modelMatrix = GLKMatrix4Identity; viewMatrix = GLKMatrix4Identity; projectionMatrix = GLKMatrix4Identity; moonMatrix = GLKMatrix4Identity; viewMatrix = GLKMatrix4MakeLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0); projectionMatrix = GLKMatrix4MakeFrustum(-1, 1, -1, 1, 8, 1000); } -(void)glkView:(GLKView *)view drawInRect:(CGRect)rect{ float aspect = (GLfloat)view.drawableWidth / (GLfloat)view.drawableHeight; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindBuffer(GL_ARRAY_BUFFER, earth); glUseProgram(_program); modelMatrix = GLKMatrix4MakeScale(1, aspect, 1); glUniformMatrix4fv(_modelMat, 1, 0, modelMatrix.m); glUniformMatrix4fv(_viewMat, 1, 0, viewMatrix.m); glUniformMatrix4fv(_projectionMat, 1, 0, projectionMatrix.m); moonMatrix = GLKMatrix4MakeScale(1, aspect, 1); moonMatrix = GLKMatrix4Translate(moonMatrix, 0.5, 0, moonDepth); glUniformMatrix4fv(_modelMat, 1, 0, moonMatrix.m); glDrawArrays(GL_TRIANGLES, 1944, 1944); glDrawArrays(GL_TRIANGLES, 0, 1944); glBindBuffer(GL_ARRAY_BUFFER, 0); } - (IBAction)changeEyePosition:(id)sender { static float i = 0.1; viewMatrix = GLKMatrix4MakeLookAt(0, 0, 10-i, 0, 0, 0, 0, 1, 0); i+=0.1; } - (IBAction)changeDistance:(id)sender { moonDepth += 0.1; // NSLog(@"%f",moonDepth); for (int i=0; i<1944; i++) { vertex[i+1944].position.x = sphereVerts[3*i]+0.1; vertex[i+1944].position.y = sphereVerts[3*i+1]; vertex[i+1944].position.z = sphereVerts[3*i+2]+moonDepth; vertex[i+1944].normal.x = sphereNormals[3*i]; vertex[i+1944].normal.y = sphereNormals[3*i+1]; vertex[i+1944].normal.z = sphereNormals[3*i+2]; vertex[i+1944].color = GLKVector4Make(1, 0.5, 1, 1); } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (BOOL)loadShaders { GLuint vertShader, fragShader; NSString *vertShaderPathname, *fragShaderPathname; // Create shader program. _program = glCreateProgram(); // Create and compile vertex shader. vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"]; if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) { NSLog(@"Failed to compile vertex shader"); return NO; } // Create and compile fragment shader. fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"]; if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) { NSLog(@"Failed to compile fragment shader"); return NO; } // Attach vertex shader to program. glAttachShader(_program, vertShader); // Attach fragment shader to program. glAttachShader(_program, fragShader); // Bind attribute locations. // This needs to be done prior to linking. glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); glBindAttribLocation(_program, GLKVertexAttribColor, "color"); if (![self linkProgram:_program]) { NSLog(@"Failed to link program: %d", _program); if (vertShader) { glDeleteShader(vertShader); vertShader = 0; } if (fragShader) { glDeleteShader(fragShader); fragShader = 0; } if (_program) { glDeleteProgram(_program); _program = 0; } return NO; } //modelMatrix = glGetUniformLocation(_program, "modelMatrix"); _modelMat = glGetUniformLocation(_program, "modelMatrix"); _viewMat = glGetUniformLocation(_program, "viewMatrix"); _projectionMat = glGetUniformLocation(_program, "projectionMatrix"); // _color = glGetUniformLocation(_program, "color"); // Release vertex and fragment shaders. if (vertShader) { glDetachShader(_program, vertShader); glDeleteShader(vertShader); } if (fragShader) { glDetachShader(_program, fragShader); glDeleteShader(fragShader); } return YES; } - (BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file { GLint status; const GLchar *source; source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String]; if (!source) { NSLog(@"Failed to load vertex shader"); return NO; } *shader = glCreateShader(type); glShaderSource(*shader, 1, &source, NULL); glCompileShader(*shader); #if defined(DEBUG) GLint logLength; glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength); glGetShaderInfoLog(*shader, logLength, &logLength, log); NSLog(@"Shader compile log:\n%s", log); free(log); } #endif glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); if (status == 0) { glDeleteShader(*shader); return NO; } return YES; } - (BOOL)linkProgram:(GLuint)prog { GLint status; glLinkProgram(prog); #if defined(DEBUG) GLint logLength; glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength); glGetProgramInfoLog(prog, logLength, &logLength, log); NSLog(@"Program link log:\n%s", log); free(log); } #endif glGetProgramiv(prog, GL_LINK_STATUS, &status); if (status == 0) { return NO; } return YES; } - (BOOL)validateProgram:(GLuint)prog { GLint logLength, status; glValidateProgram(prog); glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength); glGetProgramInfoLog(prog, logLength, &logLength, log); NSLog(@"Program validate log:\n%s", log); free(log); } glGetProgramiv(prog, GL_VALIDATE_STATUS, &status); if (status == 0) { return NO; } return YES; } @end ``` shader ``` attribute vec3 position; attribute vec3 normal; attribute vec4 color; attribute vec2 TextureCoords; uniform lowp mat4 modelMatrix; uniform lowp mat4 viewMatrix; uniform lowp mat4 projectionMatrix; varying lowp vec4 colorVarying; varying vec2 TextureCoordsOut; void main() { vec4 pointNormal = normalize(projectionMatrix * viewMatrix * modelMatrix * vec4(normal,1)); vec3 pNormal = normalize(vec3(pointNormal.x,pointNormal.y,pointNormal.z)); vec4 lightColor = vec4(1,0,1,1); vec3 lightDirection = normalize(vec3(1,0,1)); float lightStrength = dot(lightDirection,pNormal); colorVarying = color + lightStrength * lightColor; gl_Position = vec4(position,1);//projectionMatrix * viewMatrix * modelMatrix * vec4(position,1); }
glCreateProgram返回0
如题,opengles3.0随书源码,绘制三角形的程序 // The MIT License (MIT) // // Copyright (c) 2013 Dan Ginsburg, Budirijanto Purnomo // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // // Book: OpenGL(R) ES 3.0 Programming Guide, 2nd Edition // Authors: Dan Ginsburg, Budirijanto Purnomo, Dave Shreiner, Aaftab Munshi // ISBN-10: 0-321-93388-5 // ISBN-13: 978-0-321-93388-1 // Publisher: Addison-Wesley Professional // URLs: http://www.opengles-book.com // http://my.safaribooksonline.com/book/animation-and-3d/9780133440133 // // Hello_Triangle.c // // This is a simple example that draws a single triangle with // a minimal vertex/fragment shader. The purpose of this // example is to demonstrate the basic concepts of // OpenGL ES 3.0 rendering. #include "esUtil.h" typedef struct { // Handle to a program object GLuint programObject; } UserData; /// // Create a shader object, load the shader source, and // compile the shader. // GLuint LoadShader ( GLenum type, const char *shaderSrc ) { GLuint shader; GLint compiled; // Create the shader object shader = glCreateShader ( type ); if ( shader == 0 ) { return 0; } // Load the shader source glShaderSource ( shader, 1, &shaderSrc, NULL ); // Compile the shader glCompileShader ( shader ); // Check the compile status glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled ); if ( !compiled ) { GLint infoLen = 0; glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen ); if ( infoLen > 1 ) { char *infoLog = malloc ( sizeof ( char ) * infoLen ); glGetShaderInfoLog ( shader, infoLen, NULL, infoLog ); esLogMessage ( "Error compiling shader:\n%s\n", infoLog ); free ( infoLog ); } glDeleteShader ( shader ); return 0; } return shader; } /// // Initialize the shader and program object // int Init ( ESContext *esContext ) { UserData *userData = esContext->userData; char vShaderStr[] = "#version 300 es \n" "layout(location = 0) in vec4 vPosition; \n" "void main() \n" "{ \n" " gl_Position = vPosition; \n" "} \n"; char fShaderStr[] = "#version 300 es \n" "precision mediump float; \n" "out vec4 fragColor; \n" "void main() \n" "{ \n" " fragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); \n" "} \n"; GLuint vertexShader; GLuint fragmentShader; GLuint programObject; GLint linked; // Load the vertex/fragment shaders vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr ); fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr ); // Create the program object programObject = glCreateProgram ( ); if ( programObject == 0 ) { return 0; } glAttachShader ( programObject, vertexShader ); glAttachShader ( programObject, fragmentShader ); // Link the program glLinkProgram ( programObject ); // Check the link status glGetProgramiv ( programObject, GL_LINK_STATUS, &linked ); if ( !linked ) { GLint infoLen = 0; glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen ); if ( infoLen > 1 ) { char *infoLog = malloc ( sizeof ( char ) * infoLen ); glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog ); esLogMessage ( "Error linking program:\n%s\n", infoLog ); free ( infoLog ); } glDeleteProgram ( programObject ); return FALSE; } // Store the program object userData->programObject = programObject; glClearColor ( 1.0f, 1.0f, 1.0f, 0.0f ); return TRUE; } /// // Draw a triangle using the shader pair created in Init() // void Draw ( ESContext *esContext ) { UserData *userData = esContext->userData; GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f }; // Set the viewport glViewport ( 0, 0, esContext->width, esContext->height ); // Clear the color buffer glClear ( GL_COLOR_BUFFER_BIT ); // Use the program object glUseProgram ( userData->programObject ); // Load the vertex data glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices ); glEnableVertexAttribArray ( 0 ); glDrawArrays ( GL_TRIANGLES, 0, 3 ); } void Shutdown ( ESContext *esContext ) { UserData *userData = esContext->userData; glDeleteProgram ( userData->programObject ); } int esMain ( ESContext *esContext ) { esContext->userData = malloc ( sizeof ( UserData ) ); esCreateWindow ( esContext, "Hello Triangle", 320, 240, ES_WINDOW_RGB ); if ( !Init ( esContext ) ) { return GL_FALSE; } esRegisterShutdownFunc ( esContext, Shutdown ); esRegisterDrawFunc ( esContext, Draw ); return GL_TRUE; } ``` ```
Android OpenGL es 下面这段代码在模拟器2.2上可以正常 在真机上都是黑屏
测试环境:平板Android 2.3.1 和 mtk6592 cpu Android4.2.2 mtk6592 cpu Android4.2.2 还报错 09-20 15:00:30.264: E/linker(13810): load_library(linker.cpp:761): library "libmaliinstr.so" not found 09-20 15:00:30.265: E/(13810): appName=cn.it.opengl, acAppName=com.android.cts.openglperf 09-20 15:00:30.265: E/(13810): 009-20 15:00:30.266: E/(13810): appName=cn.it.opengl, acAppName=com.android.browser09-20 15:00:30.266: E/(13810): 0 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); view = new MyGLSurfaceView(this); this.setContentView(view); //渲染模式:持续渲染(默认)|命令渲染 view.setRenderer(new MyRendererCirclePoint()); //设置脏渲染(命令渲染) view.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); //请求渲染,renderer.onDrawFrame(); // view.requestRender(); } class MyGLSurfaceView extends GLSurfaceView{ public MyGLSurfaceView(Context context) { super(context); } } public class MyRendererCirclePoint implements Renderer { private float ratio; /** * 表层创建时调用该方法 */ public void onSurfaceCreated(GL10 gl, EGLConfig config) { //清屏色(黑色) gl.glClearColor(0, 0, 0, 1); //颜色缓冲和顶点缓冲区 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); } /** * 表层大小改变时调用该方法 */ public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); ratio = (float)width / height; //投影矩阵 gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity();//重置矩阵 gl.glFrustumf(-ratio, ratio, -1, 1, 3, 100);//设置平截头体 } /** * 绘图 */ public void onDrawFrame(GL10 gl) { //清除颜色缓冲去 gl.glClear(GL10.GL_COLOR_BUFFER_BIT); gl.glMatrixMode(GL10.GL_MODELVIEW);//设置模型视图矩阵 gl.glLoadIdentity(); GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0, 1, 0);//架设相机位置 /** * vertextList,顶点集合 */ float r = 0.6f ;//半径 List<Float> vertextList = new ArrayList<Float>(); float x = 0 , y = 0 , z = 0.8f ; for(float angle = 0 ; angle <= Math.PI * 6 ; angle = (float) (angle + (Math.PI / 20))){ x = (float) (r * Math.cos(angle)); y = (float) (r * Math.sin(angle)); z = z - 0.01f ; vertextList.add(x); vertextList.add(y); vertextList.add(z); } ByteBuffer vbb = ByteBuffer.allocateDirect(vertextList.size() * 4); vbb.order(ByteOrder.nativeOrder()); FloatBuffer fbb = FloatBuffer.allocate(vertextList.size()); for(Float f : vertextList){ fbb.put(f); } fbb.position(0); vbb.position(0); //设置蓝色 gl.glColor4f(0, 0, 1, 1); gl.glPointSize(5f); gl.glRotatef(-90, 1, 0, 0); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vbb); gl.glDrawArrays(GL10.GL_POINTS, 0, vertextList.size() / 3); } }
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、PDF搜索网站推荐 对于大部
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 顺便拉下票,我在参加csdn博客之星竞选,欢迎投票支持,每个QQ或者微信每天都可以投5票,扫二维码即可,http://m234140.nofollow.ax.
Vue + Spring Boot 项目实战(十四):用户认证方案与完善的访问拦截
本篇文章主要讲解 token、session 等用户认证方案的区别并分析常见误区,以及如何通过前后端的配合实现完善的访问拦截,为下一步权限控制的实现打下基础。
比特币原理详解
一、什么是比特币 比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是国家信用。去中心化电子记账系统是参与者共同记账。比特币可以防止主权危机、信用风险。其好处不多做赘述,这一层面介绍的文章很多,本文主要从更深层的技术原理角度进行介绍。 二、问题引入  假设现有4个人
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 欢迎 改进 留言。 演示地点跳到演示地点 html代码如下`&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;music&lt;/title&gt; &lt;meta charset="utf-8"&gt
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。 1. for - else 什么?不是 if 和 else 才
数据库优化 - SQL优化
前面一篇文章从实例的角度进行数据库优化,通过配置一些参数让数据库性能达到最优。但是一些“不好”的SQL也会导致数据库查询变慢,影响业务流程。本文从SQL角度进行数据库优化,提升SQL运行效率。 判断问题SQL 判断SQL是否有问题时可以通过两个表象进行判断: 系统级别表象 CPU消耗严重 IO等待严重 页面响应时间过长
2019年11月中国大陆编程语言排行榜
2019年11月2日,我统计了某招聘网站,获得有效程序员招聘数据9万条。针对招聘信息,提取编程语言关键字,并统计如下: 编程语言比例 rank pl_ percentage 1 java 33.62% 2 c/c++ 16.42% 3 c_sharp 12.82% 4 javascript 12.31% 5 python 7.93% 6 go 7.25% 7
通俗易懂地给女朋友讲:线程池的内部原理
餐厅的约会 餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”我楞了一下,心里想女朋友今天是怎么了,怎么突然问出这么专业的问题,但做为一个专业人士在女朋友面前也不能露怯啊,想了一下便说:“我先给你讲讲我前同事老王的故事吧!” 大龄程序员老王 老王是一个已经北漂十多年的程序员,岁数大了,加班加不动了,升迁也无望,于是拿着手里
经典算法(5)杨辉三角
写在前面: 我是 扬帆向海,这个昵称来源于我的名字以及女朋友的名字。我热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。 这博客是对自己学习的一点点总结及记录,如果您对 Java、算法 感兴趣,可以关注我的动态,我们一起学习。 用知识改变命运,让我们的家人过上更好的生活。 目录一、杨辉三角的介绍二、杨辉三角的算法思想三、代码实现1.第一种写法2.第二种写法 一、杨辉三角的介绍 百度
腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
昨天,有网友私信我,说去阿里面试,彻底的被打击到了。问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题。无独有偶,今天笔者又发现有网友吐槽了一道腾讯的面试题,我们一起来看看。 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹? 在互联网职场论坛,一名程序员发帖求助到。二面腾讯,其中一个算法题:64匹
面试官:你连RESTful都不知道我怎么敢要你?
面试官:了解RESTful吗? 我:听说过。 面试官:那什么是RESTful? 我:就是用起来很规范,挺好的 面试官:是RESTful挺好的,还是自我感觉挺好的 我:都挺好的。 面试官:… 把门关上。 我:… 要干嘛?先关上再说。 面试官:我说出去把门关上。 我:what ?,夺门而去 文章目录01 前言02 RESTful的来源03 RESTful6大原则1. C-S架构2. 无状态3.统一的接
为啥国人偏爱Mybatis,而老外喜欢Hibernate/JPA呢?
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行了一番讨论,感触还是有一些,于是就有了今天这篇文。 声明:本文不会下关于Mybatis和JPA两个持久层框架哪个更好这样的结论。只是摆事实,讲道理,所以,请各位看官勿喷。 一、事件起因 关于Mybatis和JPA孰优孰劣的问题,争论已经很多年了。一直也没有结论,毕竟每个人的喜好和习惯是大不相同的。我也看
SQL-小白最佳入门sql查询一
一 说明 如果是初学者,建议去网上寻找安装Mysql的文章安装,以及使用navicat连接数据库,以后的示例基本是使用mysql数据库管理系统; 二 准备前提 需要建立一张学生表,列分别是id,名称,年龄,学生信息;本示例中文章篇幅原因SQL注释略; 建表语句: CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // dosho
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,
程序员:我终于知道post和get的区别
IT界知名的程序员曾说:对于那些月薪三万以下,自称IT工程师的码农们,其实我们从来没有把他们归为我们IT工程师的队伍。他们虽然总是以IT工程师自居,但只是他们一厢情愿罢了。 此话一出,不知激起了多少(码农)程序员的愤怒,却又无可奈何,于是码农问程序员。 码农:你知道get和post请求到底有什么区别? 程序员:你看这篇就知道了。 码农:你月薪三万了? 程序员:嗯。 码农:你是怎么做到的? 程序员:
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU
加快推动区块链技术和产业创新发展,2019可信区块链峰会在京召开
      11月8日,由中国信息通信研究院、中国通信标准化协会、中国互联网协会、可信区块链推进计划联合主办,科技行者协办的2019可信区块链峰会将在北京悠唐皇冠假日酒店开幕。   区块链技术被认为是继蒸汽机、电力、互联网之后,下一代颠覆性的核心技术。如果说蒸汽机释放了人类的生产力,电力解决了人类基本的生活需求,互联网彻底改变了信息传递的方式,区块链作为构造信任的技术有重要的价值。   1
程序员把地府后台管理系统做出来了,还有3.0版本!12月7号最新消息:已在开发中有github地址
第一幕:缘起 听说阎王爷要做个生死簿后台管理系统,我们派去了一个程序员…… 996程序员做的梦: 第一场:团队招募 为了应对地府管理危机,阎王打算找“人”开发一套地府后台管理系统,于是就在地府总经办群中发了项目需求。 话说还是中国电信的信号好,地府都是满格,哈哈!!! 经常会有外行朋友问:看某网站做的不错,功能也简单,你帮忙做一下? 而这次,面对这样的需求,这个程序员
Android 9.0系统新特性,对刘海屏设备进行适配
其实Android 9.0系统已经是去年推出的“老”系统了,这个系统中新增了一个比较重要的特性,就是对刘海屏设备进行了支持。一直以来我也都有打算针对这个新特性好好地写一篇文章,但是为什么直到拖到了Android 10.0系统都发布了才开始写这篇文章呢?当然,一是因为我这段时间确实比较忙,今年几乎绝大部分的业余时间都放到写新书上了。但是最主要的原因并不是这个,而是因为刘海屏设备的适配存在一定的特殊性
网易云6亿用户音乐推荐算法
网易云音乐是音乐爱好者的集聚地,云音乐推荐系统致力于通过 AI 算法的落地,实现用户千人千面的个性化推荐,为用户带来不一样的听歌体验。 本次分享重点介绍 AI 算法在音乐推荐中的应用实践,以及在算法落地过程中遇到的挑战和解决方案。 将从如下两个部分展开: AI 算法在音乐推荐中的应用 音乐场景下的 AI 思考 从 2013 年 4 月正式上线至今,网易云音乐平台持续提供着:乐屏社区、UGC
【技巧总结】位运算装逼指南
位算法的效率有多快我就不说,不信你可以去用 10 亿个数据模拟一下,今天给大家讲一讲位运算的一些经典例子。不过,最重要的不是看懂了这些例子就好,而是要在以后多去运用位运算这些技巧,当然,采用位运算,也是可以装逼的,不信,你往下看。我会从最简单的讲起,一道比一道难度递增,不过居然是讲技巧,那么也不会太难,相信你分分钟看懂。 判断奇偶数 判断一个数是基于还是偶数,相信很多人都做过,一般的做法的代码如下
日均350000亿接入量,腾讯TubeMQ性能超过Kafka
整理 | 夕颜出品 | AI科技大本营(ID:rgznai100) 【导读】近日,腾讯开源动作不断,相继开源了分布式消息中间件TubeMQ,基于最主流的 OpenJDK8开发的
8年经验面试官详解 Java 面试秘诀
    作者 | 胡书敏 责编 | 刘静 出品 | CSDN(ID:CSDNnews) 本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三百位候选人。在本文里,就将结合本人的面试经验,针对Java初学者、Java初级开发和Java开发,给出若干准备简历和准备面试的建议。   Java程序员准备和投递简历的实
面试官如何考察你的思维方式?
1.两种思维方式在求职面试中,经常会考察这种问题:北京有多少量特斯拉汽车? 某胡同口的煎饼摊一年能卖出多少个煎饼? 深圳有多少个产品经理? 一辆公交车里能装下多少个乒乓球? 一
相关热词 c# clr dll c# 如何orm c# 固定大小的字符数组 c#框架设计 c# 删除数据库 c# 中文文字 图片转 c# 成员属性 接口 c#如何将程序封装 16进制负数转换 c# c#练手项目
立即提问