我试图在Opengl ES 2.0中使用VBO进行渲染。
我设置了vbo,它显示自己非常正确(屏幕顶部的一个三角形),我使用片段着色器显示加载的纹理,它也是正确的。
但是,TextureCoordinates都是0.0f,因此渲染全部错误(仅1种颜色)。
有我的代码:
#include "glee.h"
#include <windows.h>
#include <time.h>
#include <math.h>
HDC hDC;
const GLchar* vertexSource=
"#version 100\n"
"\n"
"attribute vec3 a_position; \n"
"attribute vec2 a_texCoord; \n"
"varying vec2 v_textcoord; \n"
"uniform sampler2D s_texture; \n"
"\n"
"void main()\n"
"{\n"
" gl_Position = vec4(a_position, 1.0);\n"
" v_textcoord = a_texCoord;\n"
"}\n";
const GLchar* fragmentSource=
"#ifdef GL_ES \n"
"precision mediump float; \n"
"#else \n"
"#version 100 \n"
"precision mediump float; \n"
"#endif \n"
"varying vec2 v_textcoord; \n"
"uniform sampler2D s_texture; \n"
"void main() {\n"
" gl_FragColor= texture2D( s_texture, v_textcoord ); \n"
" }\n";
#include <stdlib.h>
float noise(float p)
{
return (float)(rand()%(int)(p+1));
}
float fbm(float p)
{
float f =0.5000*noise(p); p*=2.01;
f+=0.2500*noise(p); p*=2.03;
f+=0.2500*noise(p); p*=2.01;
f+=0.1250*noise(p); p*=2.02;
f+=0.0625*noise(p); p*=2.02;
f/=0.9375;
return f;
}
extern "C" __declspec(noreturn) void WinMainCRTStartup()
{
HWND hWnd;
hWnd = CreateWindow("EDIT","EDIT",WS_POPUP|WS_VISIBLE, 0,0, 600, 400,0,0,0,0);
hDC = GetDC(hWnd);
// Pixel Format
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32, // Colour buffer bit depth
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32, // Depth buffer bit depth
0, 0,
PFD_MAIN_PLANE,
0, 0, 0, 0 };
SetPixelFormat(hDC, ChoosePixelFormat(hDC, &pfd), &pfd);
wglMakeCurrent(hDC,wglCreateContext(hDC));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0f,0.0f,0.0f,1.0f);
// Enable z-buffer
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glEnable(GL_CULL_FACE);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glAlphaFunc(GL_GREATER,0.1f);
glEnable(GL_BLEND);
glEnable(GL_ALPHA_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
SetForegroundWindow(hWnd);
SetFocus(hWnd);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
GLint status;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
char buffer[512];
glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
OutputDebugStringA(buffer);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
OutputDebugStringA(buffer);
glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
GLuint handle;
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &handle);
glBindTexture(GL_TEXTURE_2D, handle);
GLboolean isTex=glIsTexture(handle);
char * tbuffer=new char[4*512*512];
for (int y=0;y<512;y++)
for (int x=0;x<512;x++)
{
float f=rand()%255;
int off=(y*512)+x;
off*=4;
tbuffer[off+0]=f;
tbuffer[off+1]=f;
tbuffer[off+2]=f;
tbuffer[off+3]=255;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA
, 512
, 512
, 0
, GL_RGBA
, GL_UNSIGNED_BYTE
, tbuffer);
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_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE); // Warning: Android OpenGL GLES MUST and can ONLY receive this param
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE);
glUseProgram(shaderProgram);
int n=0;
glBindAttribLocation(shaderProgram, n++, "a_position");
glBindAttribLocation(shaderProgram, n++, "a_texCoord");
glUniform1i(glGetUniformLocation(shaderProgram, "s_texture"), 0);
GLuint texCoordLoc=glGetUniformLocation(shaderProgram, "a_texCoord");
GLuint VertexVBOID;
GLuint IndexVBOID;
struct MyVertex
{
float x, y, z; //Vertex
float nx, ny, nz; //Normal
float s0, t0; //Texcoord0
};
MyVertex pvertex[3];
//VERTEX 0
pvertex[0].x = -1.0;
pvertex[0].y = 0.0;
pvertex[0].z = 0.0;
pvertex[0].nx = 0.0;
pvertex[0].ny = 0.0;
pvertex[0].nz = 1.0;
pvertex[0].s0 = 0.0;
pvertex[0].t0 = 1.0;
//VERTEX 1
pvertex[1].x = 1.0;
pvertex[1].y = 0.0;
pvertex[1].z = 0.0;
pvertex[1].nx = 0.0;
pvertex[1].ny = 0.0;
pvertex[1].nz = 1.0;
pvertex[1].s0 = 1.0;
pvertex[1].t0 = 0.0;
//VERTEX 2
pvertex[2].x = 0.0;
pvertex[2].y = 1.0;
pvertex[2].z = 0.0;
pvertex[2].nx = 0.0;
pvertex[2].ny = 0.0;
pvertex[2].nz = 1.0;
pvertex[2].s0 = 1.0;
pvertex[2].t0 = 1.0;
glGenBuffers(1, &VertexVBOID);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*3, &pvertex, GL_STATIC_DRAW);
unsigned short pindices[6];
pindices[0] = 0;
pindices[1] = 1;
pindices[2] = 2;
pindices[3] = 0;
pindices[4] = 3;
pindices[5] = 1;
glGenBuffers(1, &IndexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*3, pindices, GL_STATIC_DRAW);
#define BUFFER_OFFSET(i) ((void*)(i))
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(0)); //The starting point of the VBO, for the vertices
glClientActiveTexture(GL_TEXTURE0);
glEnableVertexAttribArray(texCoordLoc);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(MyVertex), BUFFER_OFFSET(24)); //The starting point of texcoords, 24 bytes away
GLenum err (glGetError());
while(!GetAsyncKeyState(VK_ESCAPE) && !GetAsyncKeyState(VK_SPACE) )
{
glClearColor(0.1f,0.2f,0.3f,0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0)); //The starting point of the IBO
SwapBuffers(hDC);
MSG msg;
while (PeekMessage(&msg,0,0,0,PM_REMOVE)==0);
}
ExitProcess (0);
}
我该怎么办?我理解使用vbo,纹理坐标已经发送到着色器。有什么问题?
答案 0 :(得分:1)
你在这里得到了相当疯狂的组合。您说您使用的是ES 2.0,但是您使用了许多不属于ES 2.0的API条目。然后,您会以不兼容的方式部分混合传统和当前功能。我会尝试指出主要问题,但我可能不会详细介绍所有内容。
PIXELFORMATDESCRIPTOR
有两个看似不寻常的值。它为cColorBits
指定了32。这只是RGB组件的大小,因此每个组件8位应为24。它还为深度缓冲区指定32位,这是许多硬件不支持的值。 24是更常用的尺寸。glMatrixMode()
和glLoadIdentity()
。glAlphaFunc()
和GL_ALPHA_TEST
。glShadeModel()
。glBindAttribLocation()
之后调用glLinkProgram()
。这没有效果。您必须先致电glBindAttribLocation()
glLinkProgram()
,或glGetAttribLocation()
glLinkProgram()
。glGetUniformLocation()
号召唤a_texCoord
,这是一个属性,而不是制服。这应该是glGetAttribLocation()
。glEnableClientState()
,glVertexPointer()
和glTexCoordPointer()
。它们也与着色器代码中使用的通用顶点属性不兼容。需要使用glEnableVertexAttribArray()
和glVertexAttribPointer()
。最大的问题很可能是这个列表中的第7项和第8项,这肯定会阻止纹理坐标与任何版本的OpenGL一起使用。