代码粘贴在下面。它什么都没有。 triple
是点数组。
program = InitShader("vshader.glsl", "fshader.glsl");
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(triple), triple, GL_STATIC_DRAW);
loc = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_TRUE, 0, BUFFER_OFFSET(0));
glDrawArrays(GL_TRIANGLES, 0, n_triple / 3);
Vertex Shader(vshader.glsl)
#version 400
layout (location = 0) in vec3 vPosition; //In my previous code this varible was named VertexPosition.
void main()
{
gl_Position = vec4(vPosition, 1.0);
}
但是,如果我只删除顶点着色器的链接并将绘图方法更改为
glVertexPointer(3, GL_FLOAT, 0, triple);
它运作得很好。即使我启用了片段着色器。着色器也可以正常工作。
我只是不知道出了什么问题。
完整代码粘贴在下面:
#include "stdafx.h"
#include <windows.h>
#include <cmath>
#include<cstdlib>
#include <GL/glew.h>
#include<GL/wglew.h>
#include <GL/glut.h>
#include<iostream>
#include <cstdio>
#define BUFFER_OFFSET( offset ) ((GLvoid*) (offset))
//#pragma comment (lib, "glut32.lib")
using namespace std;
GLuint program, loc;
int w, h;
inline void point3(GLfloat points[], GLfloat x, GLfloat y, GLfloat z, int &i) {
points[i++] = x;
points[i++] = y;
points[i++] = z;
}
inline char* readShaderSource(char* shader)
{
FILE *fp;// = fopen(shader, "r");
fopen_s(&fp, shader, "r");
if (!fp)
exit(1);
fseek(fp, 0, SEEK_END);
unsigned long size = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *buf = new char [size+1];
fread_s(buf, size + 1, sizeof(char), size / sizeof(char), fp);
buf[size] = ' ';
fclose(fp);
return buf;
}
GLuint InitShader(char* vertexShader, char* fragmentShader) {
glewInit();
char* vertexSource = readShaderSource(vertexShader), *fragmentSource = readShaderSource(fragmentShader);
GLuint program;
program = glCreateProgram();
GLuint vshader = glCreateShader(GL_VERTEX_SHADER), fshader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vshader, 1, (const GLchar **)&vertexSource, NULL);
glCompileShader(vshader);
glShaderSource(fshader, 1, (const GLchar **) &fragmentSource, NULL);
glCompileShader(fshader);
GLint compiled;
glGetShaderiv(fshader, GL_COMPILE_STATUS, &compiled);
printf("%d", compiled);
GLint length;
glGetShaderiv(fshader, GL_INFO_LOG_LENGTH, &length);
char *msg = new char[length];
glGetShaderInfoLog(fshader, length, NULL, msg);
printf("\n%s\n", msg);
//glAttachShader(program, vshader);
glAttachShader(program, fshader);
GLint linked;
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &linked);
printf("%d", linked);
glUseProgram(program);
return program;
}
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WCHAR lpszClassName[] = L"Window";
WCHAR lpszTitle[] = L"Win32 Project";
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = lpszClassName;
if (!RegisterClass(&wndclass))
{
MessageBeep(0);
return FALSE;
}
HWND hwnd = CreateWindowW(lpszClassName, lpszTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
void SetupPixelFormat(HDC hDC)
{
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0,
256,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0 };
pfd.cStencilBits = 8;
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, nPixelFormat, &pfd);
}
int InitGL(GLvoid)
{
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 255.0f, 244.0f, 244.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
return TRUE;
}
void ChangeSize(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
w = width;
h = height;
}
void RenderScene()
{
static bool runned = false;
if (!runned)
{
runned = true;
//#ifdef DEBUG
FILE* fpDebugOut = NULL;
FILE* fpDebugIn = NULL;
if (!AllocConsole()) MessageBox(NULL, _T("Failed to generate console."), NULL, 0);
SetConsoleTitle(_T("Debug Window"));
_tfreopen_s(&fpDebugOut, _T("CONOUT$"), _T("w"), stdout);
_tfreopen_s(&fpDebugIn, _T("CONIN$"), _T("r"), stdin);
//#endif // DEBUG
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-2.0f, -0.0f, -5.0f);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnableClientState(GL_VERTEX_ARRAY);
const GLfloat toradix = 3.14159265358979324 / 180;
int stepper = 2, r = 2, n_triple = 0;
GLfloat *triple = (GLfloat*)malloc(sizeof(GLfloat) * 4000000);//384480
for (int j = -90 + stepper; j < 90 - stepper;j += stepper)
for (int i = -180; i <= 180;i += stepper)
{
point3(triple, r*cos(j*toradix)*sin(i*toradix), r*cos(i*toradix)*cos(j*toradix), r*sin(j*toradix), n_triple);
j += stepper;
point3(triple, r*cos(j*toradix)*sin(i*toradix), r*cos(i*toradix)*cos(j*toradix), r*sin(j*toradix), n_triple);
i += stepper;
point3(triple, r*cos(j*toradix)*sin(i*toradix), r*cos(i*toradix)*cos(j*toradix), r*sin(j*toradix), n_triple);
j -= stepper;
point3(triple, r*cos(j*toradix)*sin(i*toradix), r*cos(i*toradix)*cos(j*toradix), r*sin(j*toradix), n_triple);
}
program = InitShader("vshader.glsl", "fshader.glsl");
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * n_triple, triple, GL_STATIC_DRAW);
loc = glGetAttribLocation(program, "vPosition");
glEnableVertexAttribArray(loc);
glVertexAttribPointer(loc, 3, GL_FLOAT, GL_TRUE, 0, BUFFER_OFFSET(0));
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, n_triple / 3);
glFlush();
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static HGLRC hRC;
static HDC hDC;
switch (message) {
case WM_CREATE: {
hDC = GetDC(hwnd);
SetupPixelFormat(hDC);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
InitGL();
return 0;
}
break;
case WM_DESTROY:
{
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
PostQuitMessage(0);
}
break;
case WM_SIZE:
{
ChangeSize(LOWORD(lParam), HIWORD(lParam));
}
break;
case WM_PAINT:
{
RenderScene();
SwapBuffers(hDC);
ValidateRect(hwnd, NULL);
}
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}
答案 0 :(得分:0)
在OpenGL中,每个顶点属性(以及统一变量)都有其唯一的位置,一种指向该属性的指针。您可以将该位置硬编码为某个值,也可以让OpenGL为您决定。
// Hardcode locations in vertex shader:
layout(location = 0) in vec3 Position; // This attribute will always have the location 0
layout(location = 1) in vec2 TexCoord; // This one will use location 1
// Any location / hardcoded in program:
attribute vec4 Normal;
有关使用顶点属性here的更多信息。
使用&#34;属性&#34;要定义您的顶点属性,您可以使用 glBindAttribLocation 在程序中对其位置进行硬编码(请参阅link)。如果你没有,你就不知道它会占据什么位置。然后,您需要使用 glGetAttribLocation 查询它的位置。
在程序中,您正在搜索名为&#34; vPosition&#34;的顶点属性的位置。在顶点着色器中不存在。在顶点着色器中,您可以定义一个名为&#34; VertexPosition&#34;的属性。并将其分配给位置0.尝试替换&#34; vPosition&#34;使用&#34; VertexPosition&#34;在 glGetAttribLocation 函数中。那样 glGetAttribLocation 应该返回0因为&#34; VertexPosition&#34;被分配到顶点着色器中的该位置,输入应该有效。
您也可以尝试对值进行硬编码&#34; 0&#34;到var&#34; loc&#34;在你的程序中。这样 glEnableVertexAttribArray 和 glVertexAttribPointer 将使用位置&#34; 0&#34;它具有属性&#34; VertexPosition&#34;在顶点着色器中分配给它。